我自己永远不会这样做,但使用 Windows 机器的人坚持在文件名中添加空格。
我已经编写了这个详细的命令,除了其中包含空格的文件之外,该命令运行良好。已经尝试过一切,单引号,双引号,勾号,用反斜杠转义。
该命令应该从具有特定文件扩展名的目录中复制所有内容,但我不想复制的文件列表除外。不幸的是,其中一些文件包含空格。这是命令:
cp $(ls *.txt *.docx | grep --invert-match --fixed-strings \
-e not_this_one.txt \
-e not_this_one_either.docx \
-e "no not me.txt" \
-e "please leave me out as well.docx") ./destination_directory/
有什么想法可以让这项工作发挥作用吗?
答案1
使用find
andxargs
代替$(...)
参数扩展:
find *.txt *.docx \( \
-name not_this_one.txt \
-o -name not_this_one_either.docx \
-o -name 'no not me.txt' \
-o -name "please leave me out as well.docx" \
\) -prune -o -print0 |
xargs -0 cp -t /tmp/destination_directory
我们使用该-prune
选项来排除我们不想复制的内容。
我们使用-print0
find 命令来生成以 NUL 结尾的文件名,当通过管道传输时,xargs -0
该文件名可以正确处理包含空格的文件名。
最后,我们使用-t <target_directory>
on 选项,cp
因为这允许xargs
将文件名列表附加到命令中(如果没有-t
,目标目录需要放在最后,这会使事情变得有点复杂)。
或者,使用tar
:
tar -cf- \
--exclude=not_this_one.txt \
--exclude='not_this_one_either.docx' \
--exclude='no not me.txt' \
--exclude='please leave me out as well.docx' *.txt *.docx |
tar -C /tmp/destination_directory -xf-
(当然,您可以将排除模式列表放入文件中并使用--exclude-from
。)
答案2
一旦你发送ls *.txt *.docx
tru 一个管道,|
shell 就会生成一个字符串其中文件没有分开。好吧,它们可以用空格(或换行符)分隔,这会导致下一个尝试在空格(或换行符)上使用此类字符串拆分文件名的工具出现混乱。
由于您使用 bash 标记问题,glob 的扩展*.txt
是*.docx
由 shell (bash) 完成的,并且 bash 能够拒绝 GLOBIGNORE 中给出的某些文件模式,因此您可以简单地执行以下操作:
( GLOBIGNORE='not_this_one.txt:not_this_one_either.docx:no not me.txt:please leave me out as well.docx';
echo \
cp -t /tmp/destination_directory *.txt *.docx
)
这里(...)
是为了确保一旦子 shell 关闭,GLOBIGNORE 的设置就会被删除。当然,您可以将其删除并进行unset GLOBIGNORE
后续操作。回显是为了向您显示命令的结果。如果您对所得到的结果感到满意,请消除回声。