可能有人问过这个问题,但现有的答案对我来说没有意义。我正在一个文件夹中的多个 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