Hot answers tagged

9

awk 'FNR == 1 { f1=f2=f3=0; }; /one/ { f1++ }; /two/ { f2++ }; /three/ { f3++ }; f1 && f2 && f3 { print FILENAME; nextfile; }' * If you want to automatically handle gzipped files, either run this in a loop with zcat (slow and inefficient because you'll be forking awk many times in a loop, once ...


7

One more way, assuming GNU find(1), just for fun: find $PWD -type f -name "file.txt" -printf '%p '


6

Set record separator to . so that awk will treat whole file as a one line: awk -v RS='.' '/one/&&/two/&&/three/{print FILENAME}' * Similarly with perl: perl -ln00e '/one/&&/two/&&/three/ && print $ARGV' *


5

Because when you use just *net* (without any quoting or escaping), it will be expanded by the shell as the (existing) net file/directory in the current directory before the find command run. So the command becomes: find . -name net As you can see it is just matching net, so usbnet.ko will not be matched. Also note that, without quoting and escaping, if ...


5

You can replace the LF character with a space using the 'tr' command tr '\012' ' ' < path.txt This can be part of the original command: find $PWD -type f -name "file.txt" | tr '\012' ' ' > paths.txt


4

You can use, paste too, find . -type f -name "path.txt" -exec paste -d' ' -s {} \; > path.txt


4

One simple way would be to pipe the find output through xargs (whose default action when no explicit command is given is to echo its arguments) find $PWD -type f -name "file.txt" | xargs > paths.txt Unlike simply replacing all the newlines with spaces, this preserves the final newline.


3

For compressed files, you could loop over each file and decompress first. Then, with a slightly modified version of the other answers, you can do: for f in *; do zcat -f "$f" | perl -ln00e '/one/&&/two/&&/three/ && exit(0); }{ exit(1)' && printf '%s\n' "$f" done The Perl script will exit with 0 status (success)...


3

You can also take advantage of the fact that the shell strips newlines from command substitutions. So, instead of find $PWD -type f -name "file.txt" > paths.txt, you can do (note that you don't need the $PWD, it is the default value for find): echo $(find $PWD -type f -name "file.txt") > paths.txt or printf '%s ' $(find $PWD -type f -name "file.txt"...


3

Your command $ find . -name 'segment*' | xargs -n1 -P4 sh someFunction.sh has the effect that at most four copies of the someFunction.sh shell script will be started (-P 4) in parallel (new ones will be spawed as soon as the old ones are done), each one getting one filename as its argument (-n 1). This means that each invocation of your script will look ...


2

I think this must be one of the silliest command piplines I ever have concocted: $ find . -type l -name "Math*" -print0 | xargs -0 -n 1 -IXXX find XXX/ -type f -name "*.tex" -print0 | xargs -0 fgrep "sequ" Find all symbolic links called Math*. Do find again on each found path, looking for *.tex files. The xargs need to use -n 1 to call find with no ...


2

The find command allows you to limit what files are matched. You can then call your script with the exec option e.g. find . \( -name '*.mp3' -o -name '*.avi' \) -exec /path/to/your/script.sh Now your script will be called for each mp3/avi file in the tree. A simple test to show this would be to have script.sh read something like #!/bin/bash echo ...


2

You can do this with find alone using the -exec action: find /location -size 1033c -exec cat {} + {} will be expanded to the files found and + will enable us to read as many arguments as possible per invocation of cat, as cat can take multiple arguments. If your find does not have the + extension or you want to read the files one by one: find /location -...


2

You could use something like this assuming someFunction.sh is in your working directory. find . -name 'segment*' -print0| xargs -0 -n1 -P4 ./someFunction.sh The -print0 and -0 allow for files with spaces in the name (A common problem). In my someFunction.sh I have #!/bin/bash echo "Arg: " $1 cat $1 Which simply echo's out the file name then ...


2

Assuming your files have sane names (i.e. they don't have embedded newlines), something like this should work: find . -mtime +60 | fgrep -v -x -f exceptions.txt | xargs -d '\n' rm -f Replace rm -f with ls -1 for a dry run first. Put paths exactly as they are printed by find in exceptions.txt.


1

I don't think find has an option like this, you could build a command using printf and your exclude list: find . -name "*.txt" $(printf "! -name %s " $(cat file.txt)) -mtime +60 -exec rm -f {} + file.txt will have list of files to exclude in find command.


1

Unorthodox approach: zsh -c 'echo $PWD/**/*.gz(.om[1])' where () after *.gz means to use so called glob qualifiers, i.e.: . consider only plain files om sort by modification time [1] take only first element Obviusly if you are already using zsh you don't need to call it with zsh -c.


1

You can do that by using this command, find "$(pwd)" -type f -name "*.gz" -printf "%T@ %p\n"| sort -n | cut -d' ' -f 2 | tail -n 1


1

Your understanding of -name is correct. It only matches the file name; the path leading to the file (the chain of containing directories) is irrelevant. What you're missing is the effect of -prune. Contrast find . -name ".git" -o -print which means “if it's called .git, then do nothing, else print the path and recurse into it if it's a directory” with ...


1

To ignore the .git directories and everything underneath them you need a construct like this find . \( -name '.git' -prune \) -o \( -print {or whatever else you want to do} \) This tells find that when it finds a file or directory called .git it's to prune its tree and not descend any further down that path. Everything else can be matched - and processed -...



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