xargs: How To Control and Use Command Line Arguments
参考:
http://www.cyberciti.biz/faq/linux-unix-bsd-xargs-construct-argument-lists-utility/
http://linux.101hacks.com/linux-commands/xargs-command-examples/
http://www.computerhope.com/unix/xargs.htm
http://offbytwo.com/2011/06/26/things-you-didnt-know-about-xargs.html
http://unixhelp.ed.ac.uk/CGI/man-cgi?xargs
XARGS(1) XARGS(1)
NAME
xargs - build and execute command lines from standard input
SYNOPSIS
xargs [-0prtx] [-E eof-str] [-e[eof-str]] [--eof[=eof-str]] [--null]
[-d delimiter] [--delimiter delimiter] [-I replace-str] [-i[replace-
str]] [--replace[=replace-str]] [-l[max-lines]] [-L max-lines]
[--max-lines[=max-lines]] [-n max-args] [--max-args=max-args] [-s max-
chars] [--max-chars=max-chars] [-P max-procs] [--max-procs=max-procs]
[--interactive] [--verbose] [--exit] [--no-run-if-empty]
[--arg-file=file] [--version] [--help] [command [initial-arguments]]
DESCRIPTION
This manual page documents the GNU version of xargs. xargs reads items
from the standard input, delimited by blanks (which can be protected
with double or single quotes or a backslash) or newlines, and executes
the command (default is /bin/echo) one or more times with any initial-
arguments followed by items read from standard input. Blank lines on
the standard input are ignored.
Because Unix filenames can contain blanks and newlines, this default
behaviour is often problematic; filenames containing blanks and/or new-
lines are incorrectly processed by xargs. In these situations it is
better to use the '-0' option, which prevents such problems. When
using this option you will need to ensure that the program which pro-
duces the input for xargs also uses a null character as a separator.
If that program is GNU find for example, the '-print0' option does this
for you.
If any invocation of the command exits with a status of 255, xargs will
stop immediately without reading any further input. An error message
is issued on stderr when this happens.
OPTIONS
--arg-file=file, -a file
Read items from file instead of standard input. If you use this
option, stdin remains unchanged when commands are run. Other-
wise, stdin is redirected from /dev/null.
--null, -0
Input items are terminated by a null character instead of by
whitespace, and the quotes and backslash are not special (every
character is taken literally). Disables the end of file string,
which is treated like any other argument. Useful when input
items might contain white space, quote marks, or backslashes.
The GNU find -print0 option produces input suitable for this
mode.
--delimiter=delim, -d delim
Input items are terminated by the specified character. Quotes
and backslash are not special; every character in the input is
taken literally. Disables the end-of-file string, which is
treated like any other argument. This can be used when the
input consists of simply newline-separated items, although it is
almost always better to design your program to use '--null'
where this is possible. The specified delimiter may be a single
character, a C-style character escape such as \n, or an octal or
hexadecimal escape code. Octal and hexadecimal escape codes are
understood as for the printf command. Multibyte characters are
not supported.
-Eeof-str
Set the end of file string to eof-str. If the end of file
string occurs as a line of input, the rest of the input is
ignored. If neither -E nor -e is used, no end of file string is
used.
--eof[=eof-str], -e[eof-str]
This option is a synonym for the '-E' option. Use '-E' instead,
because it is POSIX compliant while this option is not. If eof-
str is omitted, there is no end of file string. If neither -E
nor -e is used, no end of file string is used.
--help Print a summary of the options to xargs and exit.
-I replace-str
Replace occurrences of replace-str in the initial-arguments with
names read from standard input. Also, unquoted blanks do not
terminate input items; instead the separator is the newline
character. Implies -x and -L 1.
--replace[=replace-str], -i[replace-str]
This option is a synonym for -Ireplace-str if replace-str is
specified, and for -I{} otherwise. This option is deprecated;
use -I instead.
-L max-lines
Use at most max-lines nonblank input lines per command line.
Trailing blanks cause an input line to be logically continued on
the next input line. Implies -x.
--max-lines[=max-lines], -l[max-lines]
Synonym for the -L option. Unlike -L, the max-lines argument is
optional. If max-args is not specified, it defaults to one.
The -l option is deprecated since the POSIX standard specifies
-L instead.
--max-args=max-args, -n max-args
Use at most max-args arguments per command line. Fewer than
max-args arguments will be used if the size (see the -s option)
is exceeded, unless the -x option is given, in which case xargs
will exit.
--interactive, -p
Prompt the user about whether to run each command line and read
a line from the terminal. Only run the command line if the
response starts with 'y' or 'Y'. Implies -t.
--no-run-if-empty, -r
If the standard input does not contain any nonblanks, do not run
the command. Normally, the command is run once even if there is
no input. This option is a GNU extension.
--max-chars=max-chars, -s max-chars
Use at most max-chars characters per command line, including the
command and initial-arguments and the terminating nulls at the
ends of the argument strings. The default is 131072 characters,
not including the size of the environment variables (which are
provided for separately so that it doesn't matter if your envi-
ronment variables take up more than 131072 bytes). The operat-
ing system places limits on the values that you can usefully
specify, and if you exceed these a warning message is printed
and the value actually used is set to the appropriate upper or
lower limit.
--verbose, -t
Print the command line on the standard error output before exe-
cuting it.
--version
Print the version number of xargs and exit.
--exit, -x
Exit if the size (see the -s option) is exceeded.
--max-procs=max-procs, -P max-procs
Run up to max-procs processes at a time; the default is 1. If
max-procs is 0, xargs will run as many processes as possible at
a time. Use the -n option with -P; otherwise chances are that
only one exec will be done.
EXAMPLES
find /tmp -name core -type f -print | xargs /bin/rm -f
Find files named core in or below the directory /tmp and delete them.
Note that this will work incorrectly if there are any filenames con-
taining newlines or spaces.
find /tmp -name core -type f -print0 | xargs -0 /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 con-
taining spaces or newlines are correctly handled.
cut -d: -f1 < /etc/passwd | sort | xargs echo
Generates a compact listing of all the users on the system.
xargs: How To Control and Use Command Line Arguments
Iam trying to use xargs command using shell pipes and not able to understand how to control and use command line arguments. For example I'd like to find out all *.c file located in 100s of sub-directories and move them to another directory called ~/old.src. How do I use command line args with xargs to achieve the same?
xargs command is designed to construct argument lists and invoke other utility. xargs reads items from the standard input or pipes, delimited by blanks or newlines, and executes the command one or more times with any initial-arguments followed by items read from standard input. Blank lines on the standard input are ignored.
xargs is more safer and easy to use
xargs functionality can be achived using the backquote feature of shell. But, it offers more options. It can deal with blanks or special characters in file names easily. It is often used with find, grep and other commands.
xargs examples
For example following example will print 1 2 3 4 using xargs (echo command is default)$ echo 1 2 3 4 | xargs echo
OR$ echo 1 2 3 4 | xargs
You can force xargs to use at most max-args arguments per command line. For example following will use first two argument per command:$ echo 1 2 3 4 | xargs -n 2
Find all .bak files in or below the current directory and delete them.$ find . -name "*.bak" -type f -print | xargs /bin/rm -f
{} as the argument list marker
{} is the default argument list marker. You need to use {} this with various command which take more than two arguments at a time. For example mv command need to know the file name. The following will find all .bak files in or below the current directory and move them to ~/.old.files directory:$ find . -name "*.bak" -print0 | xargs -0 -I {} mv {} ~/old.files
You can rename {} to something else. In the following example {} is renamed as file. This is more readable as compare to previous example:$ find . -name "*.bak" -print0 | xargs -0 -I file mv file ~/old.files
Where,
- -0 If there are blank spaces or characters (including newlines) many commands will not work. This option take cares of file names with blank space.
- -I Replace occurrences of replace-str in the initial-arguments with names read from standard input. Also, unquoted blanks do not terminate input items; instead the separator is the newline character.
Dealing file names with blank spaces and newline
The following will work incorrectly if there are any filenames containing newlines or spaces (it will find out all .mp3 file located in current directory and play them using mplayer):$ find . -iname "*.mp3" -print | xargs mplayer
To get rid of this problem use -0 option:$ find . -iname "*.mp3" -print0 | xargs -0 -I mp3file mplayer mp3file
To find out all *.c file located in 100s of subdirectories and move them to another directory called ~/old.src, use:$ find /path/to/dir -iname "*.c" -print0 | xargs -0 -I file mv file ~/old.src
Avoiding errors and resource hungry problems with xargs and find combo
To copy all media files to another location called /bakup/iscsi, you can use cp as follows:$ cp -r -v -p /share/media/mp3/ /backup/iscsi/mp3
However, cp command may fail if an error occurs such as if the number of files is too large for the cp command to handle. xargs in combination with find can handle such operation nicely. xargs is more resource efficient and will not halt with an error:
$ find /share/media/mp3/ -type f -name "*.mp3" -print0 | xargs -0 -r -I file cp -v -p file --target-directory=/bakup/iscsi/mp3
Please note that all of the above commands are tested with GNU/xargs version. BSD and UNIX xargs command may not have options such as -r. Please refer to your local xargs man page for further info:man xargs
Hack 22. Xargs Command Examples
xargs is a very powerful command that takes output of a command and pass it as argument of another command. Following are some practical examples on how to use xargs effectively.
Xargs Example 1:
When you are trying to delete too many files using rm, you may get error message: /bin/rm Argument list too long – Linux. Use xargs to avoid this problem.
# find ~ -name ‘*.log’ -print0 | xargs -0 rm -f
Xargs Example 2:
Get a list of all the *.conf file under /etc/. There are different ways to get the same result. Following example is only to demonstrate the use of xargs. The output of the find command in this example is passed to the ls –l one by one using xargs.
# find /etc -name "*.conf" | xargs ls –l
Xargs Example 3:
If you have a file with list of URLs that you would like to download, you can use xargs as shown below.
# cat url-list.txt | xargs wget –c
Xargs Example 4:
Find out all the jpg images and archive it.
# find / -name *.jpg -type f -print | xargs tar -cvzf images.tar.gz
Xargs Example 5:
Copy all the images to an external hard-drive.
# ls *.jpg | xargs -n1 -i cp {} /external-hard-drive/directory
Things you (probably) didn’t know about xargs
If you’ve spent any amount of time at a Unix command line you’ve probably already seen xargs
. In case you haven’t, xargs is a command used to execute commands based on arguments from standard input.
Common use cases
I often see xargs used in combination with find
in order to do something with the list of files returned by find.
Pedantic note: As people have correctly pointed out on Twitter and on Hacker News, find is a very powerful command and it has built in flags such as -exec
and -delete
that you can often use instead of piping to xargs. However people either don’t know about the options to find, forget how to invoke -exec with it’s archaic syntax, or prefer the simplicity of xargs. There are also performance implications to the various choices. I should write a follow up post on find.
Contrived examples warning: I needed something simple examples that would not detract from the topic. This is the best I could do given the time I had.Patches are welcome :)
Recursively find all Python files and count the number of linesfind . -name '*.py' | xargs wc -l
Recursively find all Emacs backup files and remove themfind . -name '*~' | xargs rm
Recursively find all Python files and search them for the word ‘import’find . -name '*.py' | xargs grep 'import'
Handling files or folders with spaces in the name
One problem with the above examples is that it does not correctly handle files or directories with a space in the name. This is because xargs by default will split on any white-space character. A quick solution to this is to tell find to delimit results with NUL (\0) characters (by supplying -print0
to find), and to tell xargs to split the input on NUL characters as well (-0
).
Remove backup files recursively even if they contain spacesfind . -name '*~' -print0 | xargs -0 rm
Security note: filenames can often contain more than just spaces.
Placement of the arguments
In the examples above xargs reads all non-white-space elements from standard input and concatenates them into the given command line before executing it. This alone is very useful in many circumstances. Sometimes however you might want to insert the arguments into the middle of a command. The -I
flag to xargs takes a string that will be replaced with the supplied input before the command is executed. A common choice is %.
Move all backup files somewhere elsefind . -name '*~' -print 0 | xargs -0 -I % cp % ~/backups
Maximum command length
Sometimes the list of arguments piped to xargs would cause the resulting command line to exceed the maximum length allowed by the system. You can find this limit with
getconf ARG_MAX
In order to avoid hitting the system limit, xargs has its own limit to the maximum length of the resulting command. If the supplied arguments would cause the invoked command to exceed this built in limit, xargs will split the input and invoke the command repeatedly. This limit defaults to 4096, which can be significantly lower than ARG_MAX on modern systems. You can override xargs’s limit with the -s
flag. This will be particularly important when you are dealing with a large source tree.
Operating on subset of arguments at a time
You might be dealing with commands that can only accept 1 or maybe 2 arguments at a time. For example the diff command operates on two files at a time. The -n
flag to xargs specifies how many arguments at a time to supply to the given command. The command will be invoked repeatedly until all input is exhausted. Note that on the last invocation you might get less than the desired number of arguments if there is insufficient input. Let’s simply use xargs to break up the input into 2 arguments per line
$ echo {0..9} | xargs -n 2
0 1
2 3
4 5
6 7
8 9
In addition to running based on a specified number of arguments at time you can also invoke a command for each line of input at a time with -L 1
. You can of course use an arbitrary number of lines a time, but 1 is most common. Here is how you might diff every git commit against its parent.
git log --format="%H %P" | xargs -L 1 git diff
Executing commands in parallel
You might be using xargs to invoke a compute intensive command for every line of input. Wouldn’t it be nice if xargs allowed you to take advantage of the multiple cores in your machine? That’s what -P
is for. It allows xargs to invoke the specified command multiple times in parallel. You might use this for example to run multiple ffmpeg
encodes in parallel. However I’m just going to show you yet another contrived example.
Parallel sleep
$ time echo {1..5} | xargs -n 1 -P 5 sleep
real 0m5.013s
user 0m0.003s
sys 0m0.014s
Sequential sleep
$ time echo {1..5} | xargs -n 1 sleep
real 0m15.022s
user 0m0.004s
sys 0m0.015s
If you are interested in using xargs for parallel computation also consider GNUparallel. xargs has the advantage of being installed by default on most systems, and easily available on BSD and OS X, but parallel has some really nice features.
If you found this post useful mention it on Twitter and follow me.
本文来自博客园,作者:摩斯电码,未经同意,禁止转载