Linux/bash, taking the list of lines on input and using xargs
to work on each line:
% ls -1 --color=never | xargs -I{} echo {}
a
b
c
Cygwin, take 1:
$ ls -1 --color=never | xargs -I{} echo {}
xargs: invalid option -- I
Usage: xargs [-0prtx] [-e[eof-str]] [-i[replace-str]] [-l[max-lines]]
[-n max-args] [-s max-chars] [-P max-procs] [--null] [--eof[=eof-str]]
[--replace[=replace-str]] [--max-lines[=max-lines]] [--interactive]
[--max-chars=max-chars] [--verbose] [--exit] [--max-procs=max-procs]
[--max-args=max-args] [--no-run-if-empty] [--version] [--help]
[command [initial-arguments]]
Cygwin, take 2:
$ ls -1 --color=never | xargs echo
a b c
(yes, I know there's a universal method of ls -1 --color=never | while read X; do echo ${X}; done
, I have tested that it works in Cygwin too, but I'm looking for a way to make xargs
work correctly in Cygwin)
Use the -n
argument of xargs
, which is really the one you should be using, as -I
is an option that serves to give the argument a 'name' so you can make them appear anywhere in the command line:
$ ls -1 --color=never | xargs echo
a b c
$ ls -1 --color=never | xargs -n 1 echo
a
b
c
From the manpage:
-n max-args
Use at most max-args arguments per command line
-I replace-str
Replace occurrences of replace-str in the initial-arguments with names read from standard input.
damienfrancois's answer is correct. You probably want to use -n
to enforce echo
to echo one file name at a time.
However, if you are really interested in taking each file and executing it one at a time, you may be better off using find
:
$ find . -maxdepth 1 --exec echo {} \;
A few things:
- This will pick up file names that begin with a period (including '.')
- This will put a
./
in front of your file names.
- The
echo
being used is from /bin/echo
and not the built in shell version of echo.
However, it doesn't depend upon the shell executing ls *
and possibility causing issues (such as coloring file names, or printing out files in sub-directories (which your command will do).
The purpose of xargs
was to minimize the execution of a particular command:
$ find . -type f | xargs foo
In this case, xargs
will execute foo
only a minimal number of times. foo
will only execute when the command line buffer gets full, or there are no more file names. However, if you are forcing an execution after each name, you're probably better off using find
. It's a lot more flexible and you're not depending upon shell behavior.