文字列のリストを別のリストに置き換える方法

文字列のリストを別のリストに置き換える方法

置き換えたい文字列が(多数)含まれているファイルがあるので、次のような簡単なコマンドを使うことを考えました。

sed 's/string1/string2/g' file1 > out  

しかし、文字列が多すぎて、手動で繰り返すことはできません。そこで、置換するすべての文字列を 1 行ずつリストにして、ファイル A という名前を付けました。次に、置換するすべての文字列のリストを作成して、ファイル B という名前を付けました。

次のような方法はありますか?

sed 's/line i of file A/line i of file B/g' file1 > out

ファイルAの各行に対して?

答え1

入力文字列と置換文字列の両方が同じ行にあるファイルを作成する方が簡単です (入力文字列にも置換文字列にもスペースが含まれていないと仮定)。次のように簡単に実行できます。

while read n k; do sed -i "s/$n/$k/g" file1; done < fileA

編集:

Nykakin さんの回答を見て、彼の提案と私の提案を組み合わせて、2 つのファイルで同じことができることに気付きました。

paste fileA fileB | while read n k; do sed -i "s/$n/$k/g" file1; done 

答え2

これは基本的に最初のアイデアですが、置換コマンドがファイルにまとめられているため、より管理しやすくなります。

tmpfile=/tmp/Asasuser.$$
実行3<ファイルA
実行4<ファイルB
読み取り中 –r 文字列 <&3
する
        読み取り –r bstring <&4
        echo "s/$astring/$bstring/" >> "$tmpfile"
終わり
実行 3<&- 4<&-
sed –f "$tmpfile" ファイル1 > 出力
rm –f "$tmpfile"

これは、fileAfileBの行数が同じであること(そしてその数が 0 より大きいこと)と、どちらにもエスケープされていない/文字が含まれていないことを前提としています。

答え3

必要なコマンドを生成するだけです。リストを含むファイルを lista と listb と呼ぶことにします。その場合、次のように使用できます。

$ for i in $(paste lista listb -d/); do echo -n "-e 's/$i/g' "; done

sed のオプションを生成します。これで eval で使用できるようになります。ファイル名が test だとします。次のように使用します:

$ eval "sed" $(for i in $(paste lista listb -d/); do echo -n "-e 's/$i/g' "; done) "test"

答え4

paste -d : fileA fileB | sed 's/\([^:]*\):\([^:]*\)/s%\1%\2%/' > sed.script
sed -f  sed.script SOURCE-FILE

SOURCE-FILE個別のファイルまたは複数のファイルのいずれかになります。fileA および fileB のテキストにはコロンやパーセント文字を含めることはできませんが、空白文字を含めることができます。

関連情報