Hot answers tagged

11

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 ...


9

You can throw away error reporting from find with 2>/dev/null, or you can avoid running the command at all: test -d /my-directory && find /my-directory -type f -mtime +14 -print0 | xargs -r0 rm As a slight optimisation and clearer code, some versions of find - including yours - can perform the rm for you directly: test -d /my/directory &&...


8

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' *


7

If you want to exclude files by name, you can use this syntax: find . -type f ! -name '*.mp3' ! -name '*.mp4' -size +1M -delete or if your find does not support delete: find . -type f ! -name '*.mp3' ! -name '*.mp4' -size +1M -exec rm {} \;


7

find -type f \( -name "*zip" -o -name "*tar" -o -name "*gz" \) -size +1M -delete the \( \) construct allows to group different filename patterns by using -delete option, we can avoid piping and troubles with xargs See this, this and this ./ or . is optional when using find command for current directory Edit: As Eric Renouf notes, if your version of ...


7

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


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


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 ...


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.


4

The -print action does have a value of true but only after it prints. Observe that this prints all the files twice: $ find . -print -print . . ./file1 ./file1 ./file2 ./file2 Despite having two print statements, this command only prints once: $ find . \( -not -print \) -print . ./file1 ./file2 Here, the first -print evaluates to true so -not -print ...


3

Use the exec command of find: find . -name someFile.java -exec javac {} \;


3

pdfunite $(sed 's/$/_*.pdf/' filenames.txt) output.pdf So if filenames.txt contains CSAI_isotig00407:342-556 CSAI_isotig00408:342-556 That command will effectively do pdfunite CSAI_isotig00407:342-556_*.pdf CSAI_isotig00408:342-556_*.pdf output.pdf


3

While doing: find /data/code/ -name "*.jar" -exec {} ls \; you are trying the execute the file found (e.g. /data/code/project/shared/build/thirdparty/log4j-1.2.8/commons-logging-1.0.4.jar) with ls as an argument to it, leading to the permission denied error. Just switch the order: find /data/code/ -name "*.jar" -exec ls {} \; GNU find has -ls option ...


3

This is a case where you should stuff the code execution into a spawned shell. find . -name '*~' -exec sh -c 'cp "$0" "${0%~}"' {} \; This way you don't need to write a script. You just do it in a one-liner. Note: You don't need the -- "end of options" specifier for cp here, because It doesn't seem to be specified in the POSIX specs for cp, and find ...


3

You seem to assume that --execdir invokes a (Bash) shell that then invokes ffmpeg. That is not the case: -exec command ; Execute command; true if 0 status is returned. All following arguments to find are taken to be arguments to the command until an argument consisting of `;' is encountered. The string `{}' ...


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 ...


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)...


2

When you invoke python3.5 -m site then python searches for a file site.py in your sys.path. This sys.path is a list determined where your python is installed and by environment variables, and various other mechanisms including the ones to recognise packages installed under site-packages. Now your matplotlib might be in one of those paths. But if you e.g. ...


2

generate a sed script from your index file (File2) instead of a loop then run that script against your File1.. It will be MUCH faster :). awk '{ print "s/sp_"$1"/"$2"/g"}' File2.txt > tranform.sed then do: sed -i -f transform.sed File1.txt so your entire script could be: awk '{ print "s/sp_"$1"/"$2"/g"}' File2.txt > transform.sed sed -f ...


2

You can do this with find, but to do it robustly you will need to embed a shell one-liner as well. The proper way to do this is one of the following: Stuff the looping into the spawned shell: find . -type f -name '._*' -exec sh -c 'for a in "$@"; do f="${a%/*}/${a##*/._}"; [ -e "$f" ] && printf %s\\n "$f"; done' find-sh {} + Or, spawn a separate ...


2

I recently wrote an example of stuffing a shell one-liner into a find command, and this is another use case for the same. Instead of: find samples \( -iname '*.wav' -o -iname '*.mp3' \) -execdir ffmpeg -i "$(basename "{}")" -qscale:a 6 "${$(basename "{}")%.*}.ogg" \; Try: find samples \( -iname '*.wav' -o -iname '*.mp3' \) -exec sh -c 'ffmpeg -i "$1" -...


2

Two possible solutions that spring to mind. 1. Iterate across all the directories in LOREM and symlink them to $HOME cd "$HOME/LOREM" for item in * do test -d "$item" || continue mv -f "$HOME/$item" "$HOME/$item.DELETE_ME_LATER" 2>/dev/null ln -s "$HOME/LOREM/$item" "$HOME/$item" done # Once you are happy that only the correct files have ...


2

You want to use the $() syntax. eg javac $(find ./someDir/anotherDir/ -name someFile.java)


2

print0 and xargs -r 0 are useless here, find has that capability builtin: [ -d /my-directory ] && find /my-directory -type f -mtime +14 -exec rm {} + or, as you are using GNU find, this variant suggested by @terdon: [ -d /my-directory ] && find /my-directory -type f -mtime +14 -delete


2

You should be able to use -execdir to make a copy relative to the directory of the found file(s) e.g. find Italy -name '*.front.*' -execdir cp -- {} 'fanart.jpg' \; Example: given $ tree Italy/ Italy/ ├── Florence │   ├── photo.back.001.jpg │   ├── photo.back.002.jpg │   ├── photo.back.003.jpg │   ├── photo.front.001.jpg │   ├── photo.front.002.jpg │   └─...


2

You can use, find /my-directory -type f -mtime +14 -print0 2>/dev/null | xargs -r0 rm Explaination: 2> /dev/null means redirects stderr to /dev/null. /dev/null is the null device it takes any input you want and throws it away. It can be used to suppress any output.


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

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 -...



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