我之前在这里有一个令人尴尬的回旋答案,但是Denis的答案提醒我,我错过了最基本的东西。因此,我删除了原始答案。但由于没有人说过这个非常基本的内容,因此我认为值得将其放在这里。
最初的问题是“我有一个文本文件,其中包含用空格分隔的文件名列表。如何将它们复制到一个目标目录中。” 起初,这似乎很棘手或复杂,因为您认为必须以某种特定方式从文件中提取项目。但是,当shell处理命令行时,它要做的第一件事是将参数列表分隔为令牌,并且(这里没有人直接说过这一点)用空格分隔令牌。(换行符也分隔标记,这就是为什么道格·哈里斯(Doug Harris)使用换行符分隔列表进行测试的结果相同的原因。)也就是说,shell期望并且已经可以处理以空格分隔的列表。
因此,您要做的就是将以空格分隔的列表(您已经拥有的列表)放在命令中的正确位置。您的命令对此有所不同:
cp file1 file2 file3...file# target
唯一的麻烦是您希望从文本文件中获取文件列表1到#。
正如Dennis在其评论中指出的那样,您的原始尝试(cp
cat list.txt new_folder
)应该已经起作用。为什么?因为内部命令cat list.txt
首先由外壳程序处理,然后扩展为file1 file2 file3...file#
,这恰恰是外壳程序在该命令部分期望和想要的。如果它不起作用,那么(1)您有错字或(2)您的文件名有些奇怪(它们有空格或其他不寻常的字符)。
所有Dennis答案都能工作的原因仅仅是因为它们提供了要处理的必要文件列表cp
,并将该列表放在整个命令中的位置。同样,命令本身的结构如下:
cp list-of-files target_directory
很容易看出这一切在此版本中如何结合在一起:
cp $(<list.txt) new_folder
$()
使外壳程序在括号内运行命令,然后在较大行中的该点替换其输出。然后,外壳将整个线贯穿起来。顺便说一句,$()
是您对反引号(`)所做的工作的更新版本。下一步:<
是文件重定向运算符。它告诉外壳将内容转储list.txt
到标准输入中。由于$()
首先处理位,因此分阶段进行以下操作:
cp $(<list.txt) new_folder
# split line into three tokens: cp, $(<list.txt), new_folder
cp file1 file2 file3...file# new_folder
# substitute result of $(<list.txt) into the larger command
显然,步骤2只是cp
您想要的普通命令。
我意识到我经常殴打这匹(也许已经死了)的马,但是我认为这是值得做的。了解究竟壳如何处理命令可以帮助您更好写,并简化了很多。它还将向您显示问题可能隐藏的位置。例如,在这种情况下,我要问的第一个问题应该是关于有趣的文件名或可能的错字。无需杂技。