我试图将文本文件中列出的文件复制到目录中,例如:
cat files.txt | xargs -I{} cp "{}" ~/Desktop/temp
但是我注意到有些文件无法复制。无法复制的文件名称中包含双空格,例如“My Document.pdf”。
我做了一些测试,简单地管道回声会删除除一个之外的所有空格。例如:
echo "Hello World" | xargs echo
只是返回
你好世界
在管道传输时有没有办法告诉它保留内容中现有的空白?
答案1
xargs
不幸的是,它对其输入进行了大量的解析,并且根据文件名中出现的字符(空格、引号/撇号、反斜杠、制表符等),它可以通过多种方式破坏它们。处理文件名的最佳方法是作为空分隔列表并使用xargs -0
(这会关闭所有解析)。如果文件列表是从 生成的find
,这会很容易(只需使用-print0
)。由于您正在处理 Perl 脚本的输出,我看到两个选项:修改 Perl 脚本以输出空值而不是换行符,或者如果您不能这样做,请使用以下命令在管道中转换它们tr
:
cat files.txt | tr "\n" "\0" | xargs -0 -I{} cp "{}" ~/Desktop/temp
答案2
我找到了一个解决方案,其中我需要用反斜杠和 OS X 上的空格替换空格。这是我想到的:
echo "Hello World" | sed 's/ /\\ /g' | xargs echo
这样所有的空间都被保留。
答案3
您可以使用while
循环:
while IFS= read -r _file
do
cp "$_file" ~/Desktop/temp
done < "files.txt"
IFS
设置为 null 会导致不执行拆分,并-r
告诉 bash 转义反斜杠字符。