7

I have the following problem. Got a file which includes certain paths/files of a FS. These for some reason do include the whole range of special characters, like space, single/double quotes, even sometimes the Copyright ASCII.

I need to run each line of the file and pass it to another command.

What I tried so far is:

<input_file xargs -I % command %

Which was working until I got this message from xargs

xargs: unmatched single quote; by default quotes are special to xargs unless you use the -0 option

But usinf this option did not work at all for me

xargs: argument line too long

Does anybody have a solution which does work ok with special characters. Doesn't have to be with xargs, but I need to pass the line as it is to the command.

Many thanks in advance.

derchris
  • 285
  • 4
  • 11
  • Technically a POSIX-compliant file name may include any byte except '\0' and '/'. So if you need to work with a set of files which names may contain "weird symbols" you should choose the only available separator '\0'. Don't know if it's possible to convert your file list into '\0'-separated list. What symbol to separate filenames is in use right now? – user3159253 Aug 21 '14 at 12:34
  • Ha, thanks for the hint. I never thought about changing the delimiter. But I did now, and it seems to work: – derchris Aug 21 '14 at 15:42
  • Picking nits, but there is no such thing as "Copyright ASCII". – n. m. could be an AI Dec 26 '21 at 15:44

2 Answers2

8

You should separate the filenames with the \0 NULL character for processing.

This can be done with

find . <args> -print0 | xargs -0

or if you must process the file with filenames, change the '\n` to '\0', e.g.

tr '\n' '\0' < filename | xargs -0 -n1 -I% echo "==%=="

the -n 1 says,

-n max-args Use at most max-args arguments per command line.

and you should to use "%" quotes to enclosing %

clt60
  • 62,119
  • 17
  • 107
  • 194
0

The xargs -0 -n1 -I% echo "==%==" solution didn't work for me on my Mac OS X, so I found another one.

<input_with_single_quotes cat | sed "s/'/\\\'/" | xargs -I {} echo {}

This replaces the ' character with \' that works well as an input to the commands in xargs.

Dharman
  • 30,962
  • 25
  • 85
  • 135
Ed Gomoliako
  • 991
  • 1
  • 8
  • 18