9

Consider the following:

$ echo index.html* | xargs -L 1 ls -l
-rw-r--r-- 1 zeki zeki  17198 2011-05-03 23:18 index.html
-rw-r--r-- 1 zeki zeki  17198 2011-05-03 23:20 index.html.1
-rw-r--r-- 1 zeki zeki  17198 2011-05-03 23:21 index.html.2
-rw-r--r-- 1 zeki zeki 146589 2011-05-05 12:29 index.html.3
$ echo index.html* | xargs -n 1 ls -l
-rw-r--r-- 1 zeki zeki 17198 2011-05-03 23:18 index.html
-rw-r--r-- 1 zeki zeki 17198 2011-05-03 23:20 index.html.1
-rw-r--r-- 1 zeki zeki 17198 2011-05-03 23:21 index.html.2
-rw-r--r-- 1 zeki zeki 146589 2011-05-05 12:29 index.html.3

Why does the -n option yield an incorrect formatting? Just in case, I'm using bash under Ubuntu. Thanks.

Fred Foo
  • 355,277
  • 75
  • 744
  • 836
ezequiel-garzon
  • 3,047
  • 6
  • 29
  • 33

3 Answers3

15

-L splits by lines; echo doesn't separate its output by lines but by spaces, so a single ls -l is run and that formats all the columns as a group.

-n splits by parameters; in the absence of -L or -0, the separator is whitespace (possibly modified by quoting), so each filename gets its own ls -l run and there is no way for the independent runs to coordinate column widths.

geekosaur
  • 59,309
  • 11
  • 123
  • 114
3

The POSIX standard mandates:

-L number

The utility shall be executed for each non-empty number lines of arguments from standard input. The last invocation of utility shall be with fewer lines of arguments if fewer than number remain. A line is considered to end with the first unless the last character of the line is a <blank>; a trailing <blank> signals continuation to the next non-empty line, inclusive.

-n number

Invoke utility using as many standard input arguments as possible, up to number (a positive decimal integer) arguments maximum.

(Emphasis added.) Since echo * produces a single line, xargs -L 1 just feeds all of the filenames to ls at once, and only then can ls nicely align the columns.

(In other words, your first command is equivalent ls -l index.html*, except that it doesn't handle filenames containing blanks correctly.)

Fred Foo
  • 355,277
  • 75
  • 744
  • 836
3

Minimal runnable example of how -L splits by lines and -n by whitespace

This should clarify what geekosaur said further:

printf '1 2\n3 4\n' | xargs -L1 echo

splits by line and therefore is equivalent to:

echo 1 2
echo 3 4

which outputs:

1 2
3 4

However:

printf '1 2\n3 4\n' | xargs -n1 echo

splits on any whitespace, and is therefore equivalent to:

echo 1
echo 2
echo 3
echo 4

and produces instead:

1
2
3
4

Also worth noting: trailing spaces make -L ignore the newline

Not sure what is the rationale, but:

printf '1 2 \n3 4\n' | xargs -L1 echo

calls echo just once and produces:

1 2 3 4

because of that space after the 2. This is documented on 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.

Portability

As mentioned at https://unix.stackexchange.com/questions/448290/are-l1-and-n-1-the-same-for-xargs/448379#448379 -L is slightly less portable as it is a XSI POSIX extension, while -n isn't.

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985