次のファイル名構造を持つファイルセットがあります。
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##*_}"