XARGS
xargs:
Execute a command, passing constructed argument list(s). The arguments are typically a long list of filenames (generated by ls or find) that are passed to xargs via a pipe.
Syntax
xargs [options] [command]
Options
-0
--null
Expect filenames to be terminated by NULL instead of whitespace.
Do not treat quotes or backslashes specially.
-e[string]
-E[string]
--eof[=string]
Set EOF to _ or, if specified, to string.
--help
Print a summary of the options to xargs and then exit.
-i[string]
-I[string]
--replace[=string]
Edit all occurrences of , or string, to the names read in
on standard input. Unquoted blanks are not considered argument terminators.
Implies -x and -l 1.
-l[lines]
-L[lines]
--max-lines[=lines]
Allow no more than 1, or lines, nonblank input lines on the command line.
Implies -x.
-n args
--max-args=args
Allow no more than args arguments on the command line.
May be overridden by -s.
-p
--interactive
Prompt for confirmation before running each command line. Implies -t.
-P max
--max-procs=max
Allow no more than max processes to run at once.
The default is 1. A maximum of 0 allows as many as possible to run at once.
-r
--no-run-if-empty
Do not run command if standard input contains only blanks.
-s max
--max-chars=max
Allow no more than max characters per command line.
-t
--verbose
Print the command line (on standard error) before executing.
-x
--exit
If the maximum size (as specified by -s) is exceeded, exit.
--version
Print the version number of xargs and then exit.
xargs can execute the command supplying some initial arguments directly, and reading the remaining arguments from standard input (or piped input).
xargs passes arguments to command in several bundles, this allows command to process more arguments than it could normally handle at once.
Arguments in the standard input must be separated by unquoted blank characters, or unescaped blank characters or newline characters.
Characters can be quoted by enclosing them in "double-quotes" (non-double-quote and non-newline chars only).Characters can be quoted by enclosing them in 'apostrophes' (non-apostrophe and non-newline chars only).Any unquoted character can be escaped by preceding it with a backslash.
/etc find . -name "*bash*"
./bash.bashrc
./bash.bash_logout
./defaults/etc/bash.bashrc
./defaults/etc/bash.bash_logout
./defaults/etc/skel/.bashrc
./defaults/etc/skel/.bash_profile
./postinstall/bash.sh.done
./setup/bash.lst.gz
./skel/.bashrc
./skel/.bash_profile
:/etc find . -name "*bash*" | xargs
./bash.bashrc ./bash.bash_logout ./defaults/etc/bash.bashrc ./defaults/etc/bash.bash_logout ./defaults/etc/skel/.bashrc ./defaults/etc/skel/.bash_profile ./postinstall/bash.sh.done ./setup/bash.lst.gz ./skel/.bashrc ./skel/.bash_profile
#find the files and then look for specific keyword on that file using grep command.
find . -name "*.java" | xargs grep "Stock"
# Remove all .tmp file from /tmp
find /tmp -name "*.tmp" | xargs rm
# If any of file name contains space or new line on it. to avoid this problem we use find -print0 to produce null separated file name and xargs-0 to handle null separated items.
"xargs splits up its input arguments at spaces (and newlines). If a file name (or path name) has spaces in it, e.g., "can not do this.pdf", xargs will misinterpret it and thinks there are multiple files.
The solution is to invoke xargs with the -0 (zero) parameter. xargs will separate filenames by NUL instead of whitespace. Also, the find command needs the -print0 parameter: this puts a NUL between filenames instead of a newline."
Characters can be quoted by enclosing them in "double-quotes" (non-double-quote and non-newline chars only).Characters can be quoted by enclosing them in 'apostrophes' (non-apostrophe and non-newline chars only).Any unquoted character can be escaped by preceding it with a backslash.
/etc find . -name "*bash*"
./bash.bashrc
./bash.bash_logout
./defaults/etc/bash.bashrc
./defaults/etc/bash.bash_logout
./defaults/etc/skel/.bashrc
./defaults/etc/skel/.bash_profile
./postinstall/bash.sh.done
./setup/bash.lst.gz
./skel/.bashrc
./skel/.bash_profile
:/etc find . -name "*bash*" | xargs
./bash.bashrc ./bash.bash_logout ./defaults/etc/bash.bashrc ./defaults/etc/bash.bash_logout ./defaults/etc/skel/.bashrc ./defaults/etc/skel/.bash_profile ./postinstall/bash.sh.done ./setup/bash.lst.gz ./skel/.bashrc ./skel/.bash_profile
#find the files and then look for specific keyword on that file using grep command.
find . -name "*.java" | xargs grep "Stock"
# Remove all .tmp file from /tmp
find /tmp -name "*.tmp" | xargs rm
# If any of file name contains space or new line on it. to avoid this problem we use find -print0 to produce null separated file name and xargs-0 to handle null separated items.
"xargs splits up its input arguments at spaces (and newlines). If a file name (or path name) has spaces in it, e.g., "can not do this.pdf", xargs will misinterpret it and thinks there are multiple files.
The solution is to invoke xargs with the -0 (zero) parameter. xargs will separate filenames by NUL instead of whitespace. Also, the find command needs the -print0 parameter: this puts a NUL between filenames instead of a newline."
Here is an example of xargs command in unix which can handle file name with spaces and newline:
find /tmp -name "*.tmp" -print0 | xargs -0 rm
#Display name of mobile companies from first column using xargs command in one line:
/etc cut -d, -f1 smartphones.csv | sort | xargs
Ashish Ash Ashi
#Command convert muti line output into single line
/perl ls -1 *.txt
derivatives.txt
futures.txt
fx.txt
options.txt
stock.txt
swaps.txt
/perl ls -1 *.txt | xargs
derivatives.txt futures.txt fx.txt options.txt stock.txt swaps.txt
ls -1 *.txt | xargs wc -l
0 derivatives.txt
2 futures.txt
0 fx.txt
1 options.txt
3 stock.txt
0 swaps.txt
ls -1 *.txt | xargs -n 2 echo
derivatives.txt futures.txt
fx.txt options.txt
stock.txt swaps.txt
Find
files named core in or below the directory /tmp and
delete them. Note that this will work incorrectly if there are any
filenames containing newlines, single or double quotes, or spaces.
#find /tmp -name core -type f -print | xargs /bin/rm -f
Find
files named core in
or below the directory /tmp and
delete them, processing filenames in such a way that file or
directory names containing single or double quotes, spaces or
newlines are correctly handled. The -name test
comes before the -type test
in order to avoid having to call stat(2) on
every file.
#find /tmp -name core -type f -print0 | xargs -0 /bin/rm -f
Run diff on file pairs (e.g., f1.a and f1.b, f2.a and f2.b ...):
Display file, one word per line (same as deroff -w):
Display file, one word per line (same as deroff -w):
env - Display, set, or remove environment variables
env - Display, set, or remove environment variables
Find's '-size' argument multiplies by 512 bytes per block, so this will give you files > 5MB:
find . -size +10000 -ls | perl -pe 's/^\d+\s\d+\s//'
To get the same calculating size in bytes, use: find . -size +5000000c -ls | perl -pe 's/^\d+\s\d+\s//'
I think this second syntax is easier, especially for getting more specific, such as +150000c to find all files above 150K.
I use Perl at the end because '-size' returns inode number and size in kilobytes as the first two columns of output, and I want a more standard 'ls -l' type of output.
I believe that using -exec forks one egrep per file encountered.
egrep -r ABC *
- Compare two drives to see if all files are identical:
- find / -path /proc -prune -o -path /new-disk -prune -o -xtype f -exec cmp {} /new-disk{} \
One of my favorite of the find criteria is used to locate files modified less than 10 minutes ago. I use this right after using some system administration tool, to learn which files got changed by that tool:
You can also find files with various permissions set. -perm /permissions means to find files with any of the specified permissions on, -perm -permissions means to find files with all of the specified permissions on, and -perm permissions means to find files with exactlypermissions. Permissions can be specified either symbolically (preferred) or with an octal number. The following will locate files that are writeable by others (including symlinks, which should be writeable by all):
When using find to locate files for backups, it often pays to use the -depth option (really a criterion that is always true), which forces the output to be depth-first—that is, files first and then the directories containing them. This helps when the directories have restrictive permissions, and restoring the directory first could prevent the files from restoring at all (and would change the time stamp on the directory in any case). Normally, find returns the directory first, before any of the files in that directory. This is useful when using the -prune action to prevent find from examining any files you want to ignore:
e.g. file1 file2 "file three" 'file four' file\ five
If command is omitted then the equivalent of /bin/echo is used.
If all invocations of command return exit status 0 then xargs will return 0, an error of 127=command not found.
Examples
Find all the .mp3 files in the music folder and pass to the ls command, -print0 is required if any filenames contain whitespace.:
find ./music -name "*.mp3" -print0 | xargs -0 ls
Find all files in the work folder, pass to grep and search for profit:
find ./work -print | xargs grep "profit"
Find and delete files which have been modified in the last 30 minutes:
find ./work -mmin -30 | xargs -0 rm
Delete all files from the work directory:
find ./work -print0 | xargs -0 rm
(Use this when rm on a large directory gives: Argument list too long)
echo $* | xargs -n2 diff
The previous line would be invoked as a shell script, specifying filenames as arguments.
cat file | xargs -n1
Move files in olddir to newdir, showing each command:
ls olddir | xargs -i -t mv olddir/ newdir/
Related:
mv files older than 7 days to a tmp directory
find . -mtime +7 -print | xargs -i -t mv {} /tmp/junk.07.29-30.2001/
mv zero-length files older than 1 days to a tmp directory
find . -mtime +1 -size 0 | xargs -i -t /bin/mv {} /usr/spool/sw_mqueue.old.junk/
MacOSX:find -inum and xargs -I % mv %
examples:
find . -inum 416504 -print0 | xargs -0 -I % mv % stuff
given
5580426 -rw-r--r-- 1 mgelbaum mgelbaum 3474 Jun 25 00:11 !
find . -maxdepth 1 -inum 5580426 | xargs -I % mv % junk1
Find a string in all files modified in the last 5 days below current working directory
find . -mtime -5 -print | xargs egrep -i vacation
Find a string in all files below current working directory
NOTE: All examples below have egrep in case-insensitive mode (-i).
#rgrep . string looks in all files
alias rgrep 'find \!:1 -type f -print|xargs egrep -i "\!:2"'
#rgrep . string looks in only in *.htm* files
alias rgreph 'find \!:1 -type f -name "*.htm*" -print|xargs egrep -i "\!:2"'
#rgrep . string _lists_ only the *.htm* that have the string
alias rgrephl 'find \!:1 -type f -name "*.htm*" -print|xargs egrep -li "\!:2
recursive grep without xargs
How-To: Find a string in all files below current working directory
find * -name "*.<extension>" -exec grep <string> {} \; -print
Find all files above 5MB, do an 'ls' on each, and chop first two columns of output
NOTE: 5MB is just an example size.
find files find files NOT owned by any user: 'find . -nouser -ls'
GNU find
GNU find trick: /vol/pub/GNU/bin/find . -maxdepth 1 -mtime -1 -print'
xargs info:
I've heard using xargs is more efficient because"xargs passes these arguments in several bundles to command, allowing the command (e.g.,egrep) to process more arguments than it could normally handle at once. The arguments to find are typically a long list of filenames (generated by ls or find, for example) that get passed to xargs via a pipe." (UNIX in a Nutshell, 2-121)
xargs info
find ./ -type f -print | xargs grep -H "ABC" /dev/null
The -print action lists the names of files separated by a newline. But it is common to pipe the output of find into xargs, which uses a space to separate file names. This can lead to a problem if any found files contain spaces in their names, as the output doesn't use any quoting. In such cases, when the output of find contains a file name such as foo bar and is piped into another command, that command sees two file names, not one file name containing a space. Even without using xargs you could have a problem if the file name contains a newline character.
Here's an example using two search criteria:
find / -type f -mtime -7 | xargs tar -rf weekly_incremental.tar
gzip weekly_incremental.tar
will find any regular files (i.e., not directories or other special files) with the criteria -type f, and only those modified seven or fewer days ago (-mtime -7). Note the use of xargs, a handy utility that coverts a stream of input (in this case the output of find) into command line arguments for the supplied command (in this case tar, used to create a backup archive).
Using the tar option -c is dangerous here; xargs may invoke tar several times if there are many files found and each -c will cause tar to over-write the previous invocation. The -rappends files to an archive. Other options such as those that would permit filenames containing spaces would be useful in a production quality backup script. option
Another use of xargs is illustrated below. This command will efficiently remove all files named core from your system (provided you run the command as root of course):
find / -name core | xargs /bin/rm -f
find / -name core -exec /bin/rm -f '{}' \; # same thing
find / -name core -delete # same if using Gnu find
(The last two forms run the rm command once per file, and are not as efficient as the first form. However the first form is safer if rewritten to use -print0.)
find / -mmin -10
(This search is also useful when I've downloaded some file but can't locate it, only in that case -cmin may work better. Keep in mind neither of these criteria is standard; -mtime and -ctime are standard, but use days and not minutes.)
Another common use is to locate all files owned by a given user (-user username). This is useful when deleting user accounts.
find . -perm -o=w
(Using -perm is more complex than this example shows. You should check both the POSIX documentation for find (which explains how the symbolic modes work) and the Gnu find man page (which describes the Gnu extensions).
find / -name /dev -prune | xargs tar ...
When specifying time with find options such as -mmin (minutes) or -mtime (24 hour periods, starting from now), you can specify a number n to mean exactly n, -n to mean less than n, and +n to mean more than n.
Another use of xargs is illustrated below. This command will efficiently remove all files named core from your system (provided you run the command as root of course):
find / -name core | xargs /bin/rm -f
Comments
Post a Comment