tags:

views:

2320

answers:

7

How can I make xargs execute the command exactly once for each line of input given? It's default behavior is to chunk the lines and execute the command once, passing multiple lines to each instance.

From http://en.wikipedia.org/wiki/Xargs:

find /path -type f -print0 | xargs -0 rm

In this example, find feeds the input of xargs with a long list of file names. xargs then splits this list into sublists and calls rm once for every sublist. This is more efficient than this functionally equivalent version:

find /path -type f -exec rm '{}' \;

I know that find has the "exec" flag. I am just quoting an illustrative example from another resource.

+8  A: 

xargs -L 1

Draemon
+1  A: 

You can limit the number of lines, or arguments (if there are spaces between each argument) using the --max-lines or --max-args flags, respectively.

  -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.
Readonly
A: 

In your example, the point of piping the output of find to xargs is that the standard behavior of find's -exec option is to execute the command once for each found file. If you're using find, and you want its standard behavior, then the answer is simple - don't use xargs to begin with.

Sherm Pendley
Actually, what I can *imply* from the OP's edits is that the input data have nothing to do with `find`, and that is why they don't prefer the `-exec` option.
ΤΖΩΤΖΙΟΥ
+2  A: 

If you want to run the command for every line (i.e. result) coming from find, then what do you need the xargs for?

Try:

find path -type f -exec your-command {} \;

where the literal {} gets substituted by the filename and the literal \; is needed for find to know that the custom command ends there.

EDIT:

(after the edit of your question clarifying that you know about -exec)

From man xargs:

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

Note that filenames ending in blanks would cause you trouble if you use xargs:

$ mkdir /tmp/bax; cd /tmp/bax
$ touch a\  b c\  c
$ find . -type f -print | xargs -L1 wc -l
0 ./c
0 ./c
0 total
0 ./b
wc: ./a: No such file or directory

So if you don't care about the -exec option, you better use -print0 and -0:

$ find . -type f -print0 | xargs -0L1 wc -l
0 ./c
0 ./c
0 ./b
0 ./a
ΤΖΩΤΖΙΟΥ
A: 
find path -type f | xargs -L1 command

is all you need.

A: 

The following command will find all the files (-type f) in /path and then copy them using cp to the current folder. Note the use if -I % to specify a placeholder character in the cp command line so that arguments can be placed after the file name.

find /path -type f -print0 | xargs -0 -I % cp % .

Tested with xargs (GNU findutils) 4.4.0

A: 

execute ant task clean-all on every build.xml on current or sub-folder.

find . -name 'build.xml' -exec ant -f {} clean-all \;
sergiofbsilva