2

Essentially I want the inverse operation performed in this question.

I'm running a search, looking for files that have Windows line endings (\r\n) as I want to remove them.

$ grep -URl ^M .

Some of the returned files have spaces in their names:

./file name 1.txt
./file name 2.txt

In order to pass this on to another tool via xargs, I need to quote the lines. How can I transform to this output instead:

"./file name 1.txt"
"./file name 2.txt"
Community
  • 1
  • 1
Drew Noakes
  • 300,895
  • 165
  • 679
  • 742

2 Answers2

6

BSD grep provides a --null option to print names followed by a null byte (instead of a newline).

GNU grep provides a -Z or --null option with the same semantics.

Both BSD and GNU xargs take a -0 option to indicate that file names are separated by null bytes.

Hence:

grep -URl --null ^M . | xargs -0 ...
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • 2
    This works nicely in this specific case as it avoids an intermediary quoted representation. I'm still curious as to how you'd produce such a quoted form though. – Drew Noakes Jan 18 '14 at 22:06
  • 1
    Note that `xargs` won't pay attention to quotes in the names, and will split at white space unless you use `-0`. If you're seeking to use the output in a `for file in $(grep -URl ...)` type construct, you have to work hard. Life was much easier when spaces in file names were eschewed as errors that were fixed by renaming the files (say, back in the 80s). You'd probably want to use single quotes rather than double quotes as otherwise you might run into problems with notations such as `$(...)` embedded in a file name. Newlines in file names are a bit problematic too. – Jonathan Leffler Jan 18 '14 at 22:13
3

To avoid the space problem I'd use new line character as separator for xargs with the -d option:

xargs -d '\n' ...

So my solution would be:

grep -URl ^M . | xargs -d '\n' rm
Ray
  • 5,269
  • 1
  • 21
  • 12