Hot answers tagged

7

You can do it with just find and awk: find . -type f -name '*.php' -size +1000c -exec awk ' FNR > 1 {nextfile} length >= 1000 {print FILENAME}' {} + The awk script skips to next file after the first line of every file. It prints the filename of the current file if the current line is >= 1000 characters long.


5

Use sort | uniq -c to count identical lines: find "$path" -type f -exec file -b {} + | sort | uniq -c | sort -nr


4

You can do a for loop on the find result and copy the folder with -R : IFS=$'\n' for source_folder in "$(find . -maxdepth 1 -type d -exec bash -c "echo -ne '{}\t'; ls '{}' | wc -l" \; | awk -F"\t" '$NF>=5{print $1}');" do if [[ "$source_folder" != "." ]]; then cp -R "$source_folder" /destination/folder fi done


4

I am not sure what your intention is (you didn't make that clear), but if it's to chmod to 700 all the files that match the pattern, then, except for your typo (;\ instead of \;), your command seems to work as intended. However: when it finds a file containing that string grep -q gives me 0 so another exec executes but should not. Yes, it should do. 0 ...


4

Here is a version that is safe for names with whitespace: find /var/log/folder -type f -printf '%T@ %p\0' | sort -rz | sed -Ezn '1s/[^ ]* //p' | xargs --null grep string How it works: find /var/log/folder -type f -printf '%T@ %p\0' This looks for files and prints their modification time (seconds) followed by a space and their name followed by a nul ...


4

With zsh, I'd do: files=($(do_something to find filenames)) (($#files)) && find $files ... With tcsh: set files=(`do_something to find filenames`) if ($#files) find $files:q ... With bash, mksh or ksh93, set -f; files=($(do_something to find filenames)) ((${#files[@]})) && find "${files[@]}" ... POSIXly: set -f; set -- ...


3

dirname of file is missing in first part, try grep -w 'sucessfully completed.' "/var/log/folder/$(ls -1rt /var/log/folder | tail -n1)" do not try ... unles there is no dir in /var/log/folder/ grep -w 'sucessfully completed.' "$(ls -1rt /var/log/folder/* | tail -n1)"


3

You can look at the "/Producer" line: find -name '*.pdf' | xargs grep -al '^/Producer (pdfTeX' or with double quotes find -name '*.pdf' | xargs grep -al "^/Producer (pdfTeX" or with null-separated list of files find -name '*.pdf' -print0 | xargs -0 grep -al '^/Producer (pdfTeX'


3

ls -1rt /path/to/files/ | tail -n1 will find the newest file in a directory (in terms of modification time); pass that as an argument to grep: grep 'string to find' "$(ls -1rt /path/to/files/ | tail -n1)"


3

Below script works for your case : find . -mindepth 1 -maxdepth 1 -type d -print0 | while read -rd '' line do files=("$line"/* "$line"/.*) count=${#files[@]};((count-=2)) if [ $count -ge 5 ] then cp -R "$line" ../newfolder/ fi done Note : This should be executed from the base folder as I am using relative paths.


3

You can use the rename command (see edit 1). Solution 1 For a reasonable number of files/directory, by setting bash 4 option globstar (not works on recursive name, see edit 3): shopt -s globstar rename -n 's/etckeeper/userkeeper/g' ** Solution 2 For a big number of files/directories using rename and find in two steps to prevent failed rename on files ...


3

Is this what you mean? find ~/ops_scripts -type f -maxdepth 1 -name "*ScheduledJobs*.txt"


3

How about doing this: paths=$(do_something to find filenames) if [ "$paths" ]; then find "$paths" ... fi This works independent from the find implementation. Note that find "$paths" with more than a single path name causes problems. If the path names do not contain spaces, you may use: find $paths, otherwise, a working alternative is this function: ...


3

? is a special character in pattern matching, which match any single character. So the command means find all files and directories in /foo/path and its subdirectories, whose names are exactly one character long. The \? is used to prevent your shell from performing filename generation. You can use other quoting mechanisms: find /foo/path -name '?' or: ...


2

If you want something more general than matching a specific character, you would have to use regular expressions. Since the question is not tagged "linux", the proper answer would use POSIX: find . | grep '[*~]' If you want to make it Linux-specific, you can use the GNU find option -regex (also supported by FreeBSD). If the pathname has an embedded ...


2

Use the -prune option to skip that directory find ~/.jenkins/jobs/subco -path ~/.jenkins/jobs/subco/myapp -prune -o -name '*.jar' -exec rm -r {} +


2

From the find(1) manpage: The -H, -L and -P options control the treatment of symbolic links. Command-line arguments following these are taken to be names of files or directories to be examined, up to the first argument that begins with -, or the argument ( or !. That argument and any following arguments are taken to ...


2

Your use of 'parent folder' is a little confusing, this will find all the folders (actually directories) in a given path, without traversing the entire tree, that are made up only of A-Z. find /given/path -type d -maxdepth 1 -regextype sed -regex ".*/[A-Z]*" For example, to do the current directory, find . -maxdepth 1 -type d -regextype sed -regex ...


2

Iterating over the subdirectories of a directory: for subdir in root_folder/*/; do if [ -L "${subdir%/}" ]; then continue; fi … done The if [ -L … line skips symbolic links to directories. Omit it if you want to include symbolic links to directories or if you know there won't be any. Directories whose name begins with a . (dot directories) won't be ...


2

No. You need to use -o (OR) in find like: find \( -iname '*.jpg' -o -iname '*.png' \) Your one would be close to correct if you are matching Regex: find -iregex ".*\(jpg\|png\)" Or using extended Regex: find -regextype posix-extended -iregex ".*(jpg|png)"


2

As others have identified, the problem with your command is that it includes directories, and tar archives them recursively. If a directory has been modified recently, all the files in it and its subdirectories get included, whether they have been modified or not. If you don't care to back up directory metadata, then just tell find not to print directory ...


2

You will not only run into problems if xargs invokes tar twice, you also will get problems if your file-names contain special characters like newlines. You should drop the use of xargs and tar and use find with cpio: find $SOURCEDIR -mtime -1 -print0 | cpio --create -0 --verbose \ --format=ustar -O $ARCHIVE ustar provides you with a POSIX.1 ...


2

find $SOURCEDIR -mtime -1 also includes $SOURCEDIR in the output, which needs to be removed before further processing Using grep -vx one can define a particular line to be excluded.. find $SOURCEDIR -mtime -1 -print | grep -xv "$SOURCEDIR" | xargs -r tar cvf $ARCHIVE || { echo "No files have been changed in the past 24 hours. Exiting script ..." ; exit ...


2

I found the problem. It seems that locate is fast because it relies upon a database it builds to search for things faster. This database is updated daily. The updatedb command does this. As it turns out, updatedb is run every 24 hours, and 24 hours hadn't passed when I tried to search for the file using locate, from the time the file was created. After ...


2

The ? is part of a mechanism called "pathname expansion" in the shell. Colloquially, the shell mechanism is called "globing". The basic glob makes use just of three characters: * ? and [ that build "patterns". An asterisk * means: Any character in any quantity (any string). A question mark (?) means: Any character one time. The square braces ...


2

Not really. Consider that find doesn't know what is in the directory tree, but finds out by reading recursively through all directory listing. (sorry for the pun.) For example there could be two first-level directories, one of which has 1 file, and another that has 1000000 files. Something like copying the tree would be different, since a program could ...


2

You can achieve this using find's -exec flag: find . -name "*.log" -exec ls -l '{}' \; In this example find searches for all log files in current directory and then list them using ls -l. In your case you should replace ls with less. See the ACTION part of find man page here find(1) man page.


2

Similar to @coffeeMug, this is the more up-to-date way to doing this as it is apparently faster: find . -name "*.log" -exec ls -l '{}' + I'll also point you to CommandLineFu, which is always helpful with these things.


2

less $(find . -name myfile.txt) less `find . -name myfile.txt` The first is, I believe, both POSIX-compliant and nest-able. The second, I believe, is more portable.


2

I'd do something like (assuming GNU tools): find /mnt/SAN/documents -type f -print0 | awk -F / ' NR == FNR{check[$0]; next} $NF in check {print "found:", $0; delete check[$NF]} END { for (i in check) print "Not found:", i }' filename.list RS='\0' - Which would find one occurrence for each filename in filename.list. Or to report all ...



Only top voted, non community-wiki answers of a minimum length are eligible