Tag Info

Hot answers tagged

7

The reason why the find command is slow That is a really interesting issue... or, honestly, mallicious: The command find . -mindepth 2 -mtime +5 -print -delete is very different from the usual tryout variant, leaving out the dangerous part, -delete: find . -mindepth 2 -mtime +5 -print The tricky part is that the action -delete implies the option ...


6

POSIX defined find -exec utility_name [argument ...] {} + as: The end of the primary expression shall be punctuated by a <semicolon> or by a <plus-sign>. Only a <plus-sign> that immediately follows an argument containing only the two characters "{}" shall punctuate the end of the primary expression. Other uses of the ...


6

and and or are not commutative in many programming languages e.g. C, C++, C♯, shells, find, and many more. They use lazy left to right evaluated i.e. it evaluates the term on the left first, and then only evaluates term on right if it needs to. So in false and b, b is not evaluated as the answer is always false. But in b and false, b is evaluated, as it has ...


5

There is a maximum length of argument list for a new process in POSIX system. find will split the execution if the files paths are longer than this. To see the limit on Linux, use xargs --show-limits (don't work in Mac OS, if someone knows a better alternative please comment here) edit: stolen straight from Gnouc's answer, the POSIX way to get the maximum ...


5

find ... -exec cmd {} + will execute cmd as many times as necessary so as not to break the limit of the size of the arguments passed to a command. When using find . -exec du {} +, the size of the file list is smaller than when using find verylongdirname -exec du {} +. So it's likely the find verylongdirname will run more du commands than the find . one. ...


5

GNUly: find . -lname '/foo*' -printf '%p\0%l\0' | awk -vRS='\0' ' { getline target sub("^/foo", "/bar", target) printf("%s\0%s\0", target, $0) }' | xargs -r0n2 ln -sfT Or with recent GNU sed: find . -lname '/foo*' -printf '%l\0%p\0' | sed -z 's|^/foo|/bar|;n' | xargs -r0n2 ln -sfT Beware that you will potentially be ...


5

The command line of find is made from different kinds of options, that are combined to form expressions. The find option -delete is an action. That means it is executed for each file matched so far. As first option after the paths, all files are matched... oops! It is dangerous - but the man page at least has a big warning: From man find: ACTIONS ...


4

You could use grep: string=testing && grep "$string" file.txt 2>&1 >/dev/null && echo "you search $string" The string "you search testing" is printed when the string "testing" is found somewhere in the file file.txt. string=testing: set the variable $string grep "$string" file.txt 2>&1 >/dev/null: grep searches for the ...


4

In find argument order matters, a lot. Arguments can be options, tests and actions. You should typically use options first, then tests, then actions. Sometimes find even warns you about a possible bad ordering (for example when you use -maxdepth after other arguments), but others it seems it doesn't. What find . -delete -name '*ar' does is: Finds files ...


4

You have so many files in /tmp that you can't fit all the names on the command line at once (the version you have is also unsafe if any paths have whitespace in them). The good news is that find can do this for you safely and correctly: find /tmp -exec touch -c '{}' + will find all the files as before, and then run touch as many times as necessary with ...


3

The direct answer to your question is grep -f /path/to/runlist /path/to/file.xml But I think this is an XY question: without thinking about how to solve the question, what are you trying to do? Given that runlist is a file containing xml filenames, I'd use an xml processing tool (like xmlstarlet) to extract the vcpu: $ cat runlist sample1.xml ...


3

Try: find ./ -name "configuration.php" -exec grep db_userXYZ /dev/null {} + POSIX defined find -exec utility_name [argument ...] {} +: If the primary expression is punctuated by a plus sign, the primary shall always evaluate as true, and the pathnames for which the primary is evaluated shall be aggregated into sets. The utility utility_name ...


3

They are not the same. -print primary is always evaluated as true and causes the current pathname to be written to standard output. When you use: \( -type f -a -print -a -iname '*.mp3' \) All files found will be printed to stdout, it's the default behavior of -print, regardless of -iname '*.mp3' expression is true or false. When you use: \( -type f -a ...


3

With ls, you can do: ls -c -ltd -- *PRO*.PLI With find: find . ! -name . -prune -type f -name '*PRO*.PLI' (note that find will include hidden files like .xPRO.PLI while the shell glob (*PRO*.PLI) will not by default).


3

This may work find build/ -type f -executable -exec sh -c 'exec "$1"' _ {} \; Or to filter to just the 001, 002 .. files find build/ -type f -name '*[0-9][0-9][0-9]' -executable -exec sh -c 'exec "$1"' _ {} \;


2

Try: $ find build/ -type f -executable | ack --nocolor "\d{3}$" | while read prog do "$prog" done


2

There is another possibility which I discovered using ACLs: the uppercase X. Given the following structure (three directories, three files): drw------- 1/ drw------- 2/ drw------- 3/ -rw------- 4 -rw------- 5 -rw------- 6 It is possible to set the execution but for directories only by using: chmod u+X * Which will result in : drwx------ 1/ drwx------ ...


2

rev and egrep and uniq are all eating your zeros and seeing a single line. If you have GNU find and uniq you can simplify this a lot: find ...tests... -printf '%h\0' | uniq -z | xargs -0 du -sh GNU find's -printf option takes a format describing the output for each file. %h is the format for the path up to but not including the filename, and then \0 makes ...


1

Another option (which may be more portable) is cd source_directory find . -type f -print0 | cpio --pass-through --null --link --make-directories dest_dir cpio (copy in&out) is a dinosaur that predates tar.  Like tar, it can create or extract from archives.  Unlike tar (correct me if I’m wrong), it can copy directory trees with a single command.  (I ...


1

You could use prename to get what you want. On some distributions (eg Debian/Ubuntu) this should be installed as default and aliased to rename. Other distros may use a different rename. You could change to the directory above the source directory and do: find source -exec prename 's:^source:/path/to/dest:' {} + This will refuse to move files that already ...


1

The main complication in your example commands is getting the directory name. You can get this much easier, directly, with the -printf option of find. It has a format for writing out the directory only: %h. Using that should allow to simplify your command a lot. To write out the directories only, use: find ... -type f ... -printf '%h\n' You can use that ...


1

The shell substitutes the result of the expression in the backticks into the line. But the system has limits on how long an argument list can be for a command. So if you have a few thousand files in /tmp, it's trying to create a command with thousands of names as an argument. This fails. There are several ways to do this more easily. Find itself can run ...


1

Why sudo? If it runs as root anyway, put it in the root crontab? Scanning a (remote) directory with thousands of files in it can take a long time. If it takes longer than a minute, you could have multiple cron jobs running concurrently, fighting one another for resources and many remote filesystems aren't able to handle concurrent accesses well. To avoid ...


1

To copy the files that are less than 30 minutes old (but don't overwrite files): find /nmt/ -cmin -30 -type f -exec cp -pn '{}' /home/pi/box/street_pictures/ \; Then to remove files in /home/pi/box/street_pictures that are older than 30 minutes find /home/pi/box/street_pictures -cmin +30 -type f -exec rm '{}' \; If each of these acts as you like you ...


1

Something like this might do what you want: find . -name '*_files' -type d -prune -o ! \( -name '*.js' -o -name '*.css' -o -name '*.png' -o -name '*.gif' -o -name '*.jpeg' \) If that prints out a reasonable list then add -print0 | xargs -o grep -i library to do the actual searching.


1

find -type f -name '00[123]' -exec env - {} \; Add in whatever environment you want to declare for the different executables. Maybe 2>/dev/null if there are non-executable 00[123] files lying around and you don't want to hear about it.


1

One of the things find is good at is selecting files that match criteria, so you can use it to pick out the files whose names consist of three digits.  And then you can use this simpler form: find build -name "[0-9][0-9][0-9]" -type f -executable -exec {} ";" And you might be able to use -regex '.*/\d{3} if you can find the right -regextype to go with ...


1

$ TODAY="cy`date '+%Y%m%d'`" $ find / -name $TODAY To see the contents of $TODAY: $ echo $TODAY $ cy20140806 If you just want it in YYMMDD format, then: $ TODAY="cy`date '+%y%m%d'`" $ find / -name $TODAY $ echo $TODAY $ cy140806 This works for me on Solaris 10. On your system, it may be different. Run a man date to see the options for your system.


1

You told du to output sizes in k, so the file is most likely smaller than 4K, but occupies that much space on disk.



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