使用通配符复制文件并添加时间戳

使用通配符复制文件并添加时间戳

我必须将文件复制Test_*.txtTest_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 的答案背后的原因,您需要循环输入文件才能达到所需的结果。

相关内容