以下の回答に従って非常に具体的な質問があります。Bashスクリプトを使用して複数のファイル名を変更する一部のファイルの名前を変更しようとしています。これは私が使用するコードです。
#!/bin/bash
for file in *.HHZ_00; do mv $file ${file/${file:14:2}/00}; done
私はこれの目的が文字インデックス14(0から始まる)の後にある2つの文字を00に置き換えることであることを理解しています。
2つのファイルサブセットでテストしています。そのうちの1つは次のとおりです。
2018113154211.25.AGCC.HHZ_00
2018113154211.25.APAC.HHZ_00
コードを実行すると、次のように名前が正常に変更されました。
2018113154211.00.AGCC.HHZ_00
2018113154211.00.APAC.HHZ_00
2番目のサブセットは失敗します。このサブセットは次のとおりです。
2018070220829.28.AGCC.HHZ_00
2018070220829.29.APAC.HHZ_00
名前は次に変更されませんでした。
2018070220829.00.AGCC.HHZ_00
2018070220800.29.APAC.HHZ_00
私が望んでいたインデックス14と15の代わりに、2番目のファイルのインデックス11と12がどのように変更されたかを確認してください。これで、非常に奇妙なことに、最後のファイルを入力として使用して2番目に実行するので、次のような結果が得られます。
2018070220829.00.AGCC.HHZ_00
2018070220800.00.APAC.HHZ_00
これは部分的に成功しましたが、2番目のファイル名が壊れています。私が何を間違っているのでしょうか?このファイルに29が重複しているためですか?
名前変更コマンドを使用する解決策がある場合は、試してみましたが、構文に慣れていません。
答え1
はい、役割が重複しているからです${file/${file:14:2}/00}
。最初位置 14-15 に表示されるすべての文字のインスタンス。
ネストされたパラメータ拡張なしでbashでこれを行う簡単な方法は次のとおりです。
$ for file in *.HHZ_00; do
echo mv "$file" "${file:0:14}00${file:16}"
done
mv 2018070220829.28.AGCC.HHZ_00 2018070220829.00.AGCC.HHZ_00
mv 2018070220829.29.APAC.HHZ_00 2018070220829.00.APAC.HHZ_00
mv 2018113154211.25.AGCC.HHZ_00 2018113154211.00.AGCC.HHZ_00
mv 2018113154211.25.APAC.HHZ_00 2018113154211.00.APAC.HHZ_00
POSIXlyでは、%%
および#
(2回)を使用して、それぞれ最長の接尾辞と最短の接頭辞を削除できます。
$ for file in *.HHZ_00; do
pfx="${file%%.*}"; rem="${file#*.}"; sfx="${rem#*.}"
echo mv "$file" "${pfx}.00.${sfx}"
done
mv 2018070220829.28.AGCC.HHZ_00 2018070220829.00.AGCC.HHZ_00
mv 2018070220829.29.APAC.HHZ_00 2018070220829.00.APAC.HHZ_00
mv 2018113154211.25.AGCC.HHZ_00 2018113154211.00.AGCC.HHZ_00
mv 2018113154211.25.APAC.HHZ_00 2018113154211.00.APAC.HHZ_00
echo
正しいことをしていると確信している場合は、削除してください。
答え2
@steeldriverは非常によく説明し、次を使用して問題を解決しました.
#!/bin/bash
for file in *.HHZ_00; do mv $file ${file/${file:13:4}/.00.}; done