我必须将文件复制Test_*.txt
到Test_20190101_Timestamp.txt
,其中*
是通配符,20190101
是日期。
cp test_*.txt test_*_"$(date +%Y%m%d-%H%M%S)".txt
当我复制文件时,输出副本也以Test_*_Timestamp.txt
.如何复制整个文件而不使用通配符?
我也尝试过这个,但也失败了
cp test_*.txt test*_"$(date +%Y%m%d-%H%M%S)".txt
cp: target 'test*_20200102-160523.txt' is not a directory
答案1
您需要循环遍历文件:
for file in Test_*.txt; do
fileroot=${file%.txt} # remove the extension
cp -v "$file" "${fileroot}_Timestamp.txt"
done
答案2
问题 - 正如您可能已经发现的 - 是您在最初的尝试中假设通配符的实际值在命令的不同参数之间“转移”(即从源文件名到预期的目标文件名)。
然而,这不是通配符扩展(或者更确切地说,“全局扩展”)在 shell 中的工作方式。相反,在任何出现通配符的地方,shell 都会在内部将其扩展为匹配文件的列表,并执行您的命令,就像您指定了整个列表一样(参见例如本教程关于 shell 通配符)。所以,如果你有文件
Test_a.txt
Test_b.txt
Test_c.txt
在您的目录中,您的cp
命令实际上会像您键入
cp Test_a.txt Test_b.txt Test_c.txt Test_*_20200102-160523.txt
由于最后一个参数被用作复制命令的目标,并且您已经指定了多个源文件,cp
因此假设这是一个目录,并抱怨不存在该名称的目录。
为什么现在它抱怨没有Test_*_20200102-160523.txt
目录字面意思 *
在里面?标准行为(至少是bash
)是,如果您指定通配符并且不存在匹配文件,则通配符将被字面解释为其本身 - 并且由于您的表达式Test_*_20200102-160523.txt
旨在作为目标文件名,因此它尚不存在在当前目录中。
这就是 @glennjackman 的答案背后的原因,您需要循环输入文件才能达到所需的结果。