Searching for exact file extension using sh or bash on macOS (syntax issue) - macos

Looking for files with .pst or .pst extension. A few apps have files in their bundles that have either/both extensions, so excluding them.
After some testing, found this script works:
#!/bin/sh
find /Users -type f -not -path "*AnApplication.app*" | grep -i "*.pst$" > /path/to/search-result.txt
exit 0
However it is returning *.dpst" files. which I thought would not happen given the grep -i "*.pst$" part of the command.
We are using the $ to ensure search returns extensions, and not files with ".pst" in the path or middle of name (Example: myFile.pst.doc or /path/my.pst.files/).
Our goal is to find only files ending in ".pst", what am I doing rong? :)

Thanks for the huge help, my apologies for the belated response. Here is what we ended up going with:
find /Users -type f -not -path '*AnApplication.app*' -iname '*.pst'

Related

bash, delete all files with a pattern name

I need to delete all files with a pattern name:  2020*.js
Inside a specific directory: server/db/migrations/
And then show what it have been deleted: `| xargs``
I'm trying this:
find . -name 'server/db/migrations/2020*.js' #-delete | xargs
But nothing is deleted, and shows nothing.
What I'm doing wrong?
The immediate problem is that -name only looks at the last component of the file name (so 2020xxx.js) and cannot match anything with a slash in it. You can use the -path predicate but the correct solution is to simply delete these files directly:
rm -v server/db/migrations/2020*.js
The find command is useful when you need to traverse subdirectories.
Also, piping the output from find to xargs does not do anything useful; if find prints the names by itself, xargs does not add any value, and if it doesn't, well, xargs can't do anything with an empty input.
If indeed you want to traverse subdirectories, try
find server/db/migrations/ -type f -name '2020*.js' -print -delete
If your shell supports ** you could equally use
rm -v server/db/migrations/**/2020*.js
which however has a robustness problem if there can be very many matching files (you get "command line too long"). In that scenario, probably fall back to find after all.
You're looking for something like this:
find server/db/migrations -type f -name '2020*.js' -delete -print
You have try this:
find . -name 'server/db/migrations/2020*.js' | xargs rm

Bash: How to use 'find' for a file with specific extension but that it would also give its previous directory

I'm quite stuck on a piece of code where I have to use 'find' to locate all files with a specific extension but that the output would also give the particular directory that the specific file is located in.
For example:
find . -name "*.exe" -o -name "*.bat" -type f
I use this code to find all files with the extension .exe and .bat and the output it gives me is:
./test/test1/test2/hello.exe
My question is would it be possible for the command to only give me the output like this:
test2/hello.exe
As in only the directory that the file is located in.
Thanks a lot in advance!
Try this:
find . -name "*.exe" -o -name "*.bat" -type f | grep -Po '[^/]*?/[^/]+$'

errors when piping a specific find command and creating a zipfile from its output?

I wish to create a program that zips whatever file is created in the directory the find parameters specify, and run it as a background process. I heavily comment it to give a better idea of what I'm trying to achieve. I'm running this from my MacBook Pro terminal, OS X version 10.9
#!/bin/sh
#find file in directory listed below
#type f to omit directories or special files
#mtime/ctime is modified/created -0 days or less
#name is with the name given in double quotes
#asterik meaning any file name with any file extension
#use xargs to convert find sequence to a command for the line after pipe
find /Users/name/thisdirectory type f -ctime -0 -name "'*'.'*'" | xargs zip -
Maybe you're looking for this:
find /path/to/dir -type f -ctime -0 -name "*.*" | zip -# file.zip
If you read zip -h, it explains that -# is to read the filenames from standard input.
You don't need xargs here, the function to work with a list of files received from standard input is built into zip itself, similar to most compression tools like tar.
Btw, I think you want to change -ctime -0, because I don't think it can match anything this way...

Find and delete .txt files in bash [duplicate]

This question already has answers here:
Command line: piping find results to rm
(5 answers)
Closed last month.
Recently frigged up my external hard drive with my photos on it (most are on DVD anyway, but..) by some partition friggery.
Fortunately I was able to put things back together with PhotoRec another Unix partition utility and PDisk.
PhotoRec returned over one thousand folders chalk full of anything from .txt files to important .NEF's.
So I tried to make the sorting easier by using unix since the OSX Finder would simply crumble under such requests as to select and delete a billion .txt files.
But I encounter some BS when I tried to find and delete txt files, or find and move all jpegs recursively into a new folder called jpegs. I am a unix noob so I need some assistance please.
Here is what I did in bash. (I am in the directory that ls would list all the folders and files I need to act upon).
find . -name *.txt | rm
or
sudo find . -name *.txt | rm -f
So it's giving me some BS that I need to unlink the files. Whatever.
I need to find all .txt files recursively and delete them preferably verbose.
You can't pipe filenames to rm. You need to use xargs instead. Also, remember to quote the file pattern ".txt" or the shell will expand it.
find . -name "*.txt" | xargs rm
find . -name "*.txt" -exec rm {} \;
$ find . -name "*.txt" -type f -delete

Finding all files with certain extension in Unix?

I have a file /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home
I am trying to find if I have the *.jdk anywhere else on my hard drive. So I do a search command:
find . -name "*.jdk"
But it doesn't find anything. Not even the one I know that I have. How come?
find . only looks in your current directory. If you have permissions to look for files in other directories (root access) then you can use the following to find your file -
find / -type f -name "*.jdk"
If you are getting tons of permission denied messages then you can suppress that by doing
find / -type f -name "*.jdk" 2> /dev/null
a/
find . means, "find (starting in the current directory)." If you want to search the whole system, use find /; to search under /System/Library, use find /System/Library, etc.
b/
It's safer to use single quotes around wildcards. If there are no files named *.jdk in the working directory when you run this, then find will get a command-line of:
find . -name *.jdk
If, however, you happen to have files junk.jdk and foo.jdk in the current directory when you run it, find will instead be started with:
find . -name junk.jdk foo.jdk
… which will (since there are two) confuse it, and cause it to error out. If you then delete foo.jdk and do the exact same thing again, you'd have
find . -name junk.jdk
…which would never find a file named (e.g.) 1.6.0.jdk.
What you probably want in this context, is
find /System -name '*.jdk'
…or, you can "escape" the * as:
find /System -name \*.jdk
Probably your JDKs are uppercase and/or the version of find available on OS X doesn't default to -print if no action is specified; try:
find . -iname "*.jdk" -print
(-iname is like -name but performs a case-insensitive match; -print says to find to print out the results)
--- EDIT ---
As noted by #Jaypal, obviously find . ... looks only into the current directory (and subdirectories), if you want to search the whole drive you have to specify / as search path.
The '.' you are using is the current directory. If you're starting in your home dir, it will probably miss the JDK files.
Worst case search is to start from root
find / -name '*.jdk' -o -name '*.JDK' -print
Otherwise replace '/' with some path you are certain should be parent to you JDK files.
I hope this helps.
If you are on Mac terminal, and also already in the directory where you want the search to be conducted at, then this may also work for you:
find *.pdf
At least it worked for me.
find / -type f -name "*.jdk" works on Mac also
This works for me on macOS.
find . -type f -iname '*.jdk'
ls *.jpg | cut -f 1 -d "."
sub out the '.jpg' to whatever extension you want to list

Resources