在bash的for循环期间向文件名添加后缀

在bash的for循环期间向文件名添加后缀

可能有人问过这个问题,但现有的答案对我来说没有意义。我正在一个文件夹中的多个 CSV 文件上运行循环。该文件夹也包含非 csv 文件,因此我必须明确指定 csv 文件。我正在使用 awk、cut 等以多种方式修改 csv 文件。完成后,我想将输出重定向到名称略有修改的新 csv 文件,如下所示:

TLC_2017.csv > TLC_2017_prepped.csv

这是一个 MWE:

for file in TLC*.csv; do
    cut -d, -f2- ${file} > ${file}_prepped
done

问题是我收到的新文件的名称如TLC_2017.csv_prepped.换句话说,后缀被添加到文件扩展名而不是名称中。如何向文件名添加后缀而不是扩展名?

如果现有问题的答案解决了我的问题,请不要仅仅链接到它,还要提供一些解释,以便我能够弄清楚。谢谢!

答案1

for file in TLC*.csv; do
    cut -d, -f2- "${file}" > "${file%.*}_prepped.csv"
done

${file%.*}删除之后的所有内容最后的的点$file.如果您想删除之后的所有内容第一的点,那么你会使用%%.

同样,${file#*.}( ${file##*.}) 会删除第一个(最后一个)点之前的所有内容。

阅读更多内容参数扩展,Bash 手册

并记住,永远引用你的变量。您可以使用shellcheck帮助您调试脚本。它会警告您有关未加引号的变量。


如果循环具有不同扩展名的文件,则目标文件扩展名不能像上面那样进行硬编码,因此${file##*.}需要。作为最小的示例,您可以在空的测试目录中尝试,这将复制_prepped到每个具有扩展名的文件:

touch A.file.txt B.file.dat C_file.csv D_file.ko E
for file in *.*; do
    noext=${file%.*}
    ext=${file##*.}
    cp "$file" "${noext}_prepped.${ext}"
done

执行后,

$ ls
A.file_prepped.txt  A.file.txt  B.file.dat  B.file_prepped.dat
C_file.csv  C_file_prepped.csv  D_file.ko  D_file_prepped.ko  E

相关内容