xargs -I replace-str option difference
From my understanding, the following should mean exactly the same:
ls -1 | xargs file {}
ls -1 | xargs -I{} file {}
if -I option is not specified, it is default to -I{}.
I want to list all files in the current directory and run file
command on each of them. Some have spaces in their names. However, I noticed the difference. See below:
$ ls -1
Hello World
$ ls -1 | xargs file {}
{}: ERROR: cannot open `{}' (No such file or directory)
Hello: ERROR: cannot open `Hello' (No such file or directory)
World: ERROR: cannot open `World' (No such file or directory)
$ ls -1 | xargs -I{} file {}
Hello World: directory
With -I{} explicitly specified, blanks in file names are treated as expected.
Solution 1:
The -I
requires a defined placeholder. The -i
option will assume {}
is the placeholder. This was where I found any assumption of {} in man xargs
at least on Cygwin and CentOS.
xargs called without either option does not need the placeholder and it just appends the STDIN to the end of the arguments.
Just add echo
to your examples to see what xargs is doing:
$ ls -1
Hello World/
Your example mistakenly uses {}
:
$ ls -1 | xargs echo file {}
file {} Hello World/
so the file
cmd sees args of {} Hello World
and errors.
If you want to explicitly use {}
in your xargs call:
$ ls -1 | xargs -I{} echo file {}
file Hello World/
Or with No placeholder:
$ ls -1 | xargs echo file
file Hello World/
xargs as called above does not need the {}. It appends the STDIN to the end of the command without a placeholder. The use of {} usually means you want the STDIN somewhere in the middle of the cmd to execute, as in:
$ ls -1 | xargs -i mv {} /path/to/someplace/.