bashでforループ中にファイル名にサフィックスを追加する

bashでforループ中にファイル名にサフィックスを追加する

この質問を受けた可能性がありますが、既存の回答は理解できません。フォルダ内の複数のCSVファイルに対してループを実行しています。フォルダにはcsv以外のファイルも含まれているため、csvファイルを明示的に指定する必要があります。私はcsvファイルをさまざまな方法で変更するためにawk、cutなどを使用しています。完了したら、次のように名前が少し変更された新しい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%.*}その後すべて削除最後point $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

関連情報