I have the fallowing command to count all image in folder "find . -type f | sed -e 's/.*.//' | sort | uniq -c | sort -n | grep -Ei '(tif| jpg| jpep| gif)$'" What do I need to add to it to have exclude a directory?
Related
I'm using pdftotext and find to find the contents of a PDF file and move it. I can find all of the files, but trying to add the mv command to the end with xargs returns "No such file or directory" for each file.
My code is as follows:
find ./ -name '*.pdf' -exec sh -c 'pdftotext "{}" - | grep -l -Z -i --with-filename --label="{}" --color "Thank you" | xargs -0 -I{} mv {} Found/' \;
Is xargs not getting the correct file path? I'm not sure what is happening.
you can get this, when the names contain spaces. Could you try this.
find ./ -name '*.pdf' -not -path "./Found/*" -exec sh -c 'pdftotext "{}" - | grep -l -Z -i --with-filename --label="{}" --color "Thank you"' \; | xargs -0 -I{} mv {} ./Found/
I'd like to search a directory structure to count the number of times I've loaded various R packages. The source is contained in .org and .R files. I'm willing to assume that "library(" is the first non-blank entry on any line I care about, and I'm willing to assume that there is at most only one such call per line.
find . -regex ".*/.*\.org" -print
gets me a list of .org files, and
find . -regex ".*\.\(org\|R\)$" -print
gets me a list of .org and .R files (thanks to https://unix.stackexchange.com/questions/15308/how-to-use-find-command-to-search-for-multiple-extensions).
Given a particular file,
grep -h "library(" file | sed 's/library(//' | sed 's/)//'
gets me the package name. I'd like to hook them together and then possibly redirect the output to a file, from which I can use R to calculate frequencies.
The seemingly straightforward
find . -regex ".*/.*\.org" -print | xargs -0 grep -h "library(" | sed 's/library(//' | sed 's/)//'
doesn't work; I get
find . -regex ".*/.*\.org" -print | xargs -0 grep -h "library(" | sed 's/library(//' | sed 's/)//'
Usage: /usr/bin/grep [OPTION]... PATTERN [FILE]...
Try '/usr/bin/grep --help' for more information.
and I'm not sure what to do next.
I also tried
find . -regex ".*/.*\.org" -exec grep -h "library(" "{}" "\;"
and got
find . -regex ".*/.*\.org" -exec grep -h "library(" "{}" "\;"
find: missing argument to `-exec'
It seems simple. What am I missing?
UPDATE: Adding -t to the above xargs shows me the first command:
grep -h library ./dirname/filename.org
followed by, presumably, a list of all the matching files with paths relative to the PWD. Actually, that works if I only search for .org files; if I add .R files, too, I get "xargs: argument line too long". I think that means xargs is passing the entire list of files as the argument to one invocation of grep.
find ... -print | xargs OK
find ... -print0 | xargs -0 OK
find ... -print0 | xargs broken
find ... -print | xargs -0 broken (what you used)
Also, please don't:
grep -h "library(" | sed 's/library(//' | sed 's/)//'
when this is faster:
grep -h "library(" | sed -e 's/library(//' -e 's/)//'
and this is even faster, and more interesting:
grep -h "library(" | grep -o '(.*)' | tr -d ' ()'
I'm trying to purge all thumbnails created by Wordpress because of a CMS switchover that I'm planning.
find -name \*-*x*.* | xargs rm -f
But I dont know bash or regex well enough to figure out how to add a bit more specifity such as only the following will be removed
All generated files have the syntax of
<img-name>-<width:integer>x<height:integer>.<file-ext> syntax
You didn't quote or escape all your wildcards, so the shell will try to expand them before find executes.
Quoting it should work
find -name '*-*x*.*'| xargs echo rm -f
Remove the echo when you're satisfied it works. You could also check that two of the fields are numbers by switching to -regex, but not sure if you need/want that here.
regex soultion
find -regex '^.*/[A-Za-z]+-[0-9]+x[0-9]+\.[A-Za-z]+$' | xargs echo rm -f
Note: I'm assuming img-name and file-ext can only contain letters
You can try this:
find -type f | grep -P '\w+-\d+x\d+\.\w+$' | xargs rm
If you have spaces in the path:
find -type f | grep -P '\w+-\d+x\d+\.\w+$' | sed -re 's/(\s)/\\\1/g' | xargs rm
Example:
find -type f | grep -P '\w+-\d+x\d+\.\w+$' | sed -re 's/(\s)/\\\1/g' | xargs ls -l
-rw-rw-r-- 1 tiago tiago 0 Jun 22 15:14 ./image-800x600.png
-rw-rw-r-- 1 tiago tiago 0 Jun 22 15:17 ./test 2/test 3/image-800x600.png
The below GNU find command will remove all the files which contain this <img-name>-<width:integer>x<height:integer>.<file-ext> syntax string. And also i assumed that the corresponding files has . in their file-names.
find . -name "*.*" -type f -exec grep -l '<img-name>-<width:integer>x<height:integer>.<file-ext> syntax' {} \; | xargs rm -f
Explanation:
. Directory in which find operation is going to takeplace.(. represnts your current directory)
-name "*.*" File must have dot in their file-names.
-type f Only files.
-exec grep -l '<img-name>-<width:integer>x<height:integer>.<file-ext> syntax' {} print the file names which contain the above mentioned pattern.
xargs rm -f For each founded files, the filename was fed into xargs and it got removed.
I need to find a text string within some files. This will give me a list:
find . -type f -print0 | xargs -0 grep -il "google"
then I need to copy those files to a folder and rename them. So I think I need to pipe them again to something like this
| xargs -0 -n1 -I '{}' cp '{}' ../testTarget/{}_RECOVERED
Alas:
find . -type f -print0 | xargs -0 grep -il "google" |
xargs -0 -n1 -I '{}' cp '{}' ../testTarget/{}_RECOVERED
Results: cp: {}: No such file or directory
Please advise
the filenames have space and commas in them (Dovecot)
find . -type f -print0 | xargs -0 grep -lh "google" | xargs -I % cp % ../testTarget/%_RECOVERED
or
find SOURCE/ -type f -print0 | xargs -0 grep -lh "SEARCH_STRING" | xargs -I % cp % TARGET_DIR/%_RECOVERED
for i in `ls -1tr`
{
SEARCH_STRING_LINE_NO=`grep -n SEARCH_STRING i | cut -d: -f1`;
if [ SEARCH_STRING_LINE_NO > 0 ] then
cp i folder_path_where_u_want_to_copy
fi
}
Replace SEARCH_STRING with the text string you want to find.
Replace folder_path_where_u_want_to_copy with the folder path where u want to move the files containing SEARCH_STRING
This should copy the files containing SEARCH_STRING to the folder folder_path_where_u_want_to_copy
I have not tested this code as I dont have a unix box with me right now, but atleast it should give u an idea to approach
The following command will grep for pattern and copy the files to your desired location.
find /path/to/search -type f -exec grep -q "pattern" '{}' ';' -exec cp '{}' /path/to/copy ';'
Once the files are copied over you can use rename command to rename them accordingly.
How can I use find to identify those directories that do not contain a file with a specified name? I want to create a file that contains a list of all directories missing a certain file.
Find directories:
find -type d > DIRS
Find directories with the file:
find -type f -name 'SpecificName' | sed 's!/[^/]*$!!' > FILEDIRS
Find the difference:
grep DIRS -vf FILEDIRS
There are quite a few different ways you could go about this - here's the approach I would take (bash assumed):
while read d
do
[[ -r ${d}/SpecificFile.txt ]] || echo ${d}
done < <(find . -type d -print)
If your target directories only exist at a certain depth, there are other options you could add to find to limit the number of directories to check...
This is an example for a file main.cpp. In the example all directories that do not contain main.cpp in them are found. As you see I first get a list of all folders, then get a list of folders having main.cpp and then run diff to get a difference between the two lists:
diff \
<(find . -exec readlink -f {} \; | sed 's/\(.*\)\/.*$/\1/' | sort | uniq) \
<(find . -name main.cpp -exec readlink -f {} \; | sed 's/\(.*\)\/.*$/\1/' | sort | uniq) \
| sed -n 's/< \(.*\)/\1/p'