coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Inconsistent behavior of core utilities


From: Dominique Martinet
Subject: Re: Inconsistent behavior of core utilities
Date: Tue, 23 Aug 2022 09:50:20 +0900

Dave Close wrote on Mon, Aug 22, 2022 at 03:01:11PM -0700:
>   $ grep CALL ./* | wc
>   16325   61444  950870
>   $ grep CALL $( ls ./* ) | wc
>   16375   61601  953451
> 
> So I almost have a solution. Except the extra 50 lines found in the
> second command are disturbing. Thus far, it appears that those lines
> are duplicates and some of the duplicated lines are from files with
> names that do not contain any special characters.

That is because this is not correct either.
Just don't use ls for thing, `find -print0` is just about the only thing
that can handle arbitrary filenames (well, direct shell expansions also
mostly work with care; but I'll assume your example is oversimplified
otherwise you wouldn't be trying to use ls... right?)

It's probably easier to understand with a concrete example:
$ echo a > one
$ echo a > one\ one

$ grep a $(ls ./*)
./one:a
./one:a
one:a

See here how the arguments got split as the space, so the 'one' file got
listed three times instead of handling both files once.


As for quoting:

$ grep a $(ls --quoting-style=shell-escape-always ./*)
grep: './one': No such file or directory
grep: './one: No such file or directory
grep: one': No such file or directory

As you can see here the quotes from shell escaping are treated as
literals, you'd get something that appears to be what you want with an
extra eval:
$ eval grep a $(ls --quoting-style=shell-escape-always ./*)
./one:a
./one one:a

but it's hardly something I would recommend.



Anyway, here's an example for find -print0:

$ find . -type f -print0 | xargs -0 grep a --
./one one:a
./one:a

--
Dominique



reply via email to

[Prev in Thread] Current Thread [Next in Thread]