如何使用xargs复制文件名中包含空格和引号的文件?
如何使用xargs复制文件名中包含空格和引号的文件?
我试图复制一个目录下的一堆文件,其中一些文件的名称中包含空格和单引号。当我尝试使用find
和grep
与xargs
串联起来时,出现以下错误:\n
find .|grep "FooBar"|xargs -I{} cp "{}" ~/foo/bar xargs: 未终止的引号
\n有没有更健壮的使用xargs
的建议?\n这是在< a href=\"http://en.wikipedia.org/wiki/Mac_OS_X_Leopard\" rel=\"noreferrer\">Mac OS X 10.5.3(Leopard)上使用的BSD xargs
。
问题的出现原因是xargs命令的默认分隔符对于包含空格和引号的文件名来说太宽泛了,需要将其缩小范围。在Mac上,使用默认的xargs命令不能解决这个问题。
解决方法是改变分隔符,将其从任意空白字符改为行结束符。可以通过以下命令来实现:
find whatever ... | xargs -d "\n" cp -t /var/tmp
另外,在Mac上也可以通过将find
命令的输出通过管道传递给sed -e 's_\(.*\)_"\1"_g'
来强制文件名周围加上引号。这个方法可以解决问题,但不是使用xargs命令来解决的。
然而,需要注意的是在许多*nix系统中,文件名可以包含换行符。尽管在实际应用中很少会遇到这个问题,但如果在不可信的输入上运行shell命令时,这可能是一个问题。
对于使用Mac的用户来说,需要安装GNU工具才能使用-d
选项。
在这个对话中,问题的出现是因为文件名中包含空格和引号,而在使用xargs复制文件时遇到了问题。为了解决这个问题,可以使用以下方法:首先,使用find命令查找文件并使用-print0选项打印文件名,然后使用grep命令过滤文件名并使用--null选项指定文件名以空字符结尾。最后,使用xargs命令将这些文件复制到目标目录。
具体来说,可以使用以下命令来解决问题:
find . -print0 | grep --null 'FooBar' | xargs -0 ...
需要注意的是,在Leopard操作系统上,grep命令支持--null选项,xargs命令支持-0选项。然而,在OS X Mountain Lion (10.8)中,苹果用BSD grep替换了GNU grep,并且-{z|Z}选项不起作用。在OS X 10.9中,grep -{z|Z}
表示"像zgrep那样运行"(解压缩),而不是原本的意图"在每个文件名后打印一个零字节"。可以使用grep --null
来实现后者。
此外,如果使用grep时遇到Binary file (standard input) matches
的错误,可能是因为使用了-print0选项。可以使用grep -a
强制其解释管道。
另外一个可能遇到的问题是,将以0结尾的文件名传递给duperemove命令会导致No such file or directory
错误。解决方法是正确使用xargs命令,可以使用xargs -d '\n'
来替代-0
,这样可以避免xargs在空格处截断文件名。
最后,如果需要传递其他参数(例如目标目录)给cp命令,可以使用... | xargs -0 -J % cp -v % /target/dir
这样的语法。
以上是解决使用xargs复制文件名中包含空格和引号的问题的方法。
问题的出现原因是在使用xargs命令复制带有空格和引号的文件名时遇到了困难。解决方法是使用find命令结合-exec选项来复制这些文件。
下面是解决问题的具体步骤:
1. 使用find命令来查找带有特定文件名的文件。可以使用-iname选项来进行不区分大小写的搜索。例如,使用-iname "*foobar*"可以找到文件名中包含"foobar"的文件。
2. 使用-exec选项来执行复制操作。在-exec选项后面加上cp命令,并使用{}来表示找到的文件名。例如,-exec cp -- "{}" ~/foo/bar会将找到的文件复制到~/foo/bar目录中。
3. 为了处理文件名和目录中的空格,可以使用-name选项来获取区分大小写的结果。这样可以确保find命令正确处理带有空格的文件名。
4. 注意,传递给cp命令的--选项可以防止它将以-开头的文件名作为选项进行处理。
5. 使用xargs命令的一个原因是它通常比多次调用具有多个参数的命令更快。xargs命令可以将参数分成适当的组大小。
6. 另一个解决方法是使用find命令的-print0选项结合xargs命令的--null选项来处理带有空格的文件名。这种方法在处理大量文件时可以显著提高速度。
7. 还有一种更好的解决方法是使用cp命令的-t选项。这样可以避免为每个文件运行一次cp命令,从而减少了fork+execve的开销。
总结起来,要使用xargs命令复制带有空格和引号的文件名,可以使用find命令的-exec选项结合cp命令来实现。另外,还可以使用xargs命令的--null选项和find命令的-print0选项来提高处理速度。