为什么这有效
for X in A* ; do cp $X/output.txt output/$X.txt ; done
但不是这个
cp A*/output.txt output/A*.txt
将 output.txt 文件从名为 A1、A2、A3、A4 等的多个文件夹复制到名为“output”的组合文件夹中,并为每个文本文件赋予其来源文件夹的名称。
答案1
由于壳体将零件展开A*.txt
至多种的在传递给正在调用的命令之前的路径(cp
在本例中)。
这意味着在第一种情况下,如果您有名为 A1.txt、A2.txt、A3.txt 和 A4.txt 的文件,并且目录 A1、A2、A3 和 A4 分别包含 output.txt,它将扩展为就像是:
for X in A1.txt A2.txt A3.txt A4.txt ; do cp $X/output.txt output/$X.txt ; done
在第二种情况下,它扩展为:
cp A1/output.txt A2/output.txt A3/output.txt A4/output.txt output/A*.txt
其中该output/A*.txt
部分可能会扩展,也可能不会扩展,这取决于output
目录中是否存在与 glob 匹配的内容。如果存在,情况会变得更糟,例如:
cp A1/output.txt A2/output.txt A3/output.txt A4/output.txt output/A8.txt output/A9.txt
因为cp
当给定多个源文件时想要一个目标目录最后,它不知道如何处理这个问题,只是举手投降并给你一个错误。
答案2
原因是,如果 有两个以上的参数cp
,则最后一个必须是一个目录。cp 手册页状态:
概要
cp [选项]...[-T] 源 目标
cp [选项]... 源... 目录
cp [选项]... -t 目录源...
描述
将 SOURCE 复制到 DEST,或将多个 SOURCE 复制到 DIRECTORY。
你写的命令,
cp file1 file2 file3 file4
意思是
cp file1 file3; cp file2 file4
但事实并非如此,原因如上所述。for 循环反而会产生上述 2 条语句,而这正是您真正想要的。