I'm trying to copy a bunch of files below a directory and a number of the files have spaces and single-quotes in their names. When I try to string together find
and grep
with xargs
, I get the following error:
find .|grep "FooBar"|xargs -I{} cp "{}" ~/foo/bar
xargs: unterminated quote
Any suggestions for a more robust usage of xargs?
This is on Mac OS X 10.5.3 (Leopard) with BSD xargs
.
The easiest way to do what the original poster wants is to change the delimiter from any whitespace to just the end-of-line character like this:
I ran into the same problem. Here's how I solved it:
I used
sed
to substitute each line of input with the same line, but surrounded by double quotes. From thesed
man page, "...An ampersand (``&'') appearing in the replacement is replaced by the string matching the RE..." -- in this case,.*
, the entire line.This solves the
xargs: unterminated quote
error.Here is a portable (POSIX) solution, i.e. one that doesn't require
find
,xargs
orcp
GNU specific extensions:It will correctly handle files and directories with embedded spaces, newlines or whatever, and is more efficient (i.e. faster) than the accepted and most if not all of the other answers.
bill_starr's Perl version won't work well for embedded newlines (only copes with spaces). For those on e.g. Solaris where you don't have the GNU tools, a more complete version might be (using sed)...
adjust the find and grep arguments or other commands as you require, but the sed will fix your embedded newlines/spaces/tabs.
If you are using Bash, you can convert stdout to an array of lines by
mapfile
:The benefits are:
You can append other arguments to the file names. For
cp
, you can also:however, some commands don't have such feature.
The disadvantages:
Well... who knows if Bash is available on OS X?
For me, I was trying to do something a little different. I wanted to copy my .txt files into my tmp folder. The .txt filenames contain spaces and apostrophe characters. This worked on my Mac.