ファイル名を変更し、部分文字列を変数の値に変更します。

ファイル名を変更し、部分文字列を変数の値に変更します。

次のファイル名構造を持つファイルセットがあります。

aa_bbbbb_cccccccc_dddddd.txt

3番目の要素をファイルの内容から抽出したcccccccc変数の値に置き換えたいと思います。value

ファイル名の4つのコンポーネントの値が変更されたため、文字列置換を使用して置き換えることはできませんが、置き換えたい部分文字列の場所を基準に置き換える必要があります。

bashスクリプトのみを使用してこの問題を解決する方法について提案がありますか?


名前変更は使用できません。 cygwinでは動作しないようで、とにかく文字列置換は使用できません。 "_"を区切り文字と見なす場合は、3番目のフィールドを変数に含まれる値で置き換える必要があります。

答え1

bash実際、kshまたはPOSIXの演算子と同じくらい厄介な分割演算子がありますsh。引用符なしで引数を拡張すると、IFS分割が実行されます。

cmd $var

する$var$IFS悪名高い分割+グローブ演算子とも呼ばれる文字を分割し、ワイルドカードも行います。

通常、オプションを受け入れるコマンドのcmd "$var"場合でも通常必要なため、望ましくありません。cmd -- "$var"

ただし、ここでは分割に使用できます_

そして:

IFS=_
set -o noglob
parts=( $file'' )

$file分割され、_結果の部分が配列$partsに格納されます。

これにより、次のことができます。

parts[2]=$value

3番目の部分を変更します(bashではkshと同じですが、他のほとんどのシェルとは異なり、配列要素のインデックス付けは0から始まるため、3番目の要素にあります${parts[2]})。

_以下を使用してパックに追加できます。

newfile="${parts[*]}"

答え2

value変数を含むファイルの例

value=xxx

その後、使用真珠rename:

file=aa_bbbbb_cccccccc_dddddd.txt
rename -n 's/^(.+?_.+?)_.+?_(.*)/${1}_foo_$2/' ./"$file"

出力がうまくいったら削除してください-n(別名)。dry-run

答え3

使用Bash パラメータ拡張:

  • ${parameter##word}word一致する最も長いプレフィックスパターンを削除します。parameter
  • ${parameter%word}word最短一致サフィックスパターンの削除parameter
file="aa_bbbbb_cccccccc_dddddd.txt"
value="replace me"

suffix=${file##*_}  # dddddd.txt
prefix=${file%_*}   # aa_bbbbb_cccccccc
prefix=${prefix%_*} # aa_bbbbb

mv "$file" "${prefix}_${value}_${suffix}"

またはより短い

file="aa_bbbbb_cccccccc_dddddd.txt"
value="replace me"
prefix=${file%_*}

mv "$file" "${prefix%_*}_${value}_${file##*_}"

関連情報