
次のスクリプトに問題があります (これが関連する部分です)。
#!/bin/bash
OLD=(
"_MAIN1_"
"_MAIN2_"
)
NEW=(
"#111"
"#222"
)
length=${#OLD[*]}
i=0
while (( i < length ))
do
sed -e "s/${OLD[$i]}/${NEW[$i]}/g" oldfile.txt > newfile.txt
#sed -e 's/_MAIN1_/#111/g' oldfile.txt > newfile.txt # this works
# Another way that does not work
#sed -e 's/'"${OLD[$i]}"'/'"${NEW[$i]}"'/g' oldfile.txt > newfile.txt
((i++))
done
exit 0
私の目標は、ファイル内の文字列を置き換えて新しいファイルに保存することです。「古い」文字列と「新しい」文字列は配列に格納されます。
いろいろ試して、一重引用符と二重引用符をいろいろ試してみましたが、何も機能しませんでした。echo
変数を使用すると、ループ内で正しい文字列が取得されます。コマンドで明示的に 2 つの文字列が設定されている場合は、sed
これで正常に動作します。
文字列パターンは、私のサンプル配列のパターンに従います (「new」にはアンダースコア「_」が含まれ、「old」にはハッシュタグ「#」が含まれます)。
Ubuntu 16.04 ボックスで bash を実行しています。
どうもありがとうございます!
答え1
すべての置換を実行するスクリプトを作成しsed
、そのsed
スクリプトをファイルに適用します。
for (( i=0; i<${#OLD[@]}; ++i )); do
printf 's/%s/%s/g\n' "${OLD[$i]}" "${NEW[$i]}"
done >script.sed
sed -f script.sed inputfile >outputfile && mv outptufile inputfile && rm script.sed
この方法では、入力ファイルを解析する必要がある回数を 1 回に制限します。
与えられたデータに対してOLD
、NEW
スクリプトsed
は次のように生成されます。
s/_MAIN1_/#111/g
s/_MAIN2_/#222/g
答え2
スクリプト全体 (動作しません) は、次の 1 行に置き換えることができます。
sed 's/_MAIN\([12]\)_/#\1\1\1/g' oldfile.txt > newfile.txt
または、より読みやすく、同等の表現は次のようになります。
sed 's/_MAIN1_/#111/g;s/_MAIN2_/#222/g' oldfile.txt > newfile.txt
これを達成するには、あなたの状況に応じて、他にも数十の方法が存在します。実際の使用事例 (例: データの取得元、値の実際の形式、データを使用して何をしようとしているかなど)。