xargs
xargs & quotes
xargs treats quotes differently than the shell (bash, for example).
$ printf '"foo"bar"' | xargs printf %s\\n
xargs: unmatched double quote; by default quotes are special
to xargs unless you use the -0 option
Excerpt from man 1 xargs
-0
--null
Input items are terminated by a null character instead of by
whitespace, and the quotes and backslash are not special (every
character is taken literally). Disables the end-of-file string,
which is treated like any other argument. Useful when input items
might contain white space, quote marks, or backslashes. The GNU
find (and from POSIX Issue 8, IEEE Std 1003.1, 2024) -print0
option produces input suitable for this mode.
Therefore:
$ printf '"foo"bar"' | xargs --null printf %s\\n
"foo"bar"
And, if we escape a quote with a backslash, nothing changes from the output above:
$ printf '"foo\"bar"' | xargs --null printf %s\\n
"foo"bar"
Note that the backslash is not printed. As far as I understand it, when a backslash scape escapes a character that is not treated in a special way, the escape does nothing.
And there is also --delimiter=delim:
Excerpt from man 1 xargs
-d delim
--delimiter=delim
Input items are terminated by the specified character. The
specified delimiter may be a single character, a C-style character
escape such as \n, or an octal or hexadecimal escape code. Octal
and hexadecimal escape codes are understood as for the printf
command. Multibyte characters are not supported. When processing
the input, quotes and backslash are not special; every character
in the input is taken literally. The -d option disables any
end-of-file string, which is treated like any other argument. You
can use this option when the input consists of simply
newline-separated items, although it is almost always better to
design your program to use --null where this is possible.
So if we use --delimiter, “quotes and backslashes are not special; every character in the input is taken literally”:
$ printf '"foo\"bar"' | xargs -d \\0 printf %s\\n
"foo"bar"