ファイルの文字列を変数に格納されている他のファイルの文字列に置き換えます。

ファイルの文字列を変数に格納されている他のファイルの文字列に置き換えます。

ファイル内の文字列を別の文字列に置き換えたいのですが、両方と同じ.特殊文字(この場合は文字)があります。1.02.0

現在使用されているコマンドは次のとおりです。

sed -i 's/1\.0/2\.0/g' /home/user1/file1.txt

1.0andが2.0変数andに保存された場合はどう$iなりますか$ji価値はどこにありますか1.0j価値は何で2.0あり、何に置き換えることiができますかj

答え1

これを使用してsed問題を解決できます。

printf '%s\n' "$i" "$j" |
sed 's/[]\$*&/.^[]/\\&/g;H;$!d
     x;y|\n|/|;s|.*|s&/g|' |
sed -f - /path/to/infile

したがって、このs///置換は入力のすべてのBREメタ文字をエスケープします。

s/[]\$*&/.^[]/\\&/g

...それぞれの前にバックスラッシュを付けます。その後、最初の項目はsed最初の行$iのコピーを保存します。H古いスペースにewline文字を追加して保存します\n$iその後、その行は最後の行ではないdため削除されます。次の行(この行)は最後の行でもあります。最初の行と同じ処理を受けた後は、次のようになります。!$$jいいえ d選択。代わりに、x保持バッファとモードバッファを変更し、接続結果に従って動作します。この時点で、パターン空間は次のようになります。

\n1\.0\n2\.0

...それで、私たちはy///すべての\n行を/スラッシュに変換し、s///すべてをパターン空間自体と接頭辞と接尾辞に置き換えることで次のようになります。.*&s/g

s/1\.0/2\.0/g

その後、stdinをスクリプトとしてsed読み取る2番目のファイルに自動的に印刷されます。-f -最初の作業がsed完了してパイプ間を閉じると、2番目の作業がsed適用され始めます。

s/1\.0/2\.0/g

...ここにある入力ファイルの各行名を指定します/path/to/infile

私は次のようにファイルを書きました。

printf '%04s%04s%04s%04s\n' \
        0 0 -1 0 1 0 0 0 0 -1\
        0 0 1.5 2.0 1.0 0 >/tmp/temp

これは私に次のようなものを与えます...

   0   0  -1   0
   1   0   0   0
   0  -1   0   0
 1.5 2.0 1.0   0

その後、別のバージョンのスクリプトを作成しました。たとえば、次のようになります。

ii=0.0
for i in        1.0 2.0 3.0 4.0
do      str2=$i
        printf '\033[41m## %s \033[0m\n' \
                "str2 = $str2" "$ii $str2"
        printf %s\\n "$ii" "$str2"
        ii=$str2
done | 
sed '   s/[]\$^&*./[]/\\&/g;H;x
        s|^\(\n\)\(.*\)\n\(.*\)\n\(.*\)\n\(.*\)|\
        bs\5\1:i\5\1i\\\1\2\\\1\3\1:s\5\1s/\4/\5/gp;ti\5|p
        s|||;h;d' |
sed -f - /tmp/temp

文字列を生成するためにシェルのみを使用しますが、sedすべてのデータ処理を実行できます。sed2つが呼び出されても、それぞれが一度だけ呼び出されます。

実行すると、結果は次のようになります。

   0   0  -1   0
   1   0   0   0
   0  -1   0   0
 1.5 2.0 2.0   0
## str2 = 2.0 
## 1.0 2.0 
 1.5 3.0 3.0   0
## str2 = 3.0 
## 2.0 3.0 
 1.5 4.0 4.0   0
## str2 = 4.0 
## 3.0 4.0 
 1.5 4.0 4.0   0

#予想通りに始まる行は赤で表示されます。sed交換が成功した場合にのみ記録されます。s///2番目のスクリプト用に作成された最初のスクリプトはsed次のとおりです。

                bs1\.0
:i1\.0
i\
[41m## str2 = 1\.0 [0m\
[41m## 0\.0 1\.0 [0m
:s1\.0
s/0\.0/1\.0/gp;ti1\.0

                bs2\.0
:i2\.0
i\
[41m## str2 = 2\.0 [0m\
[41m## 1\.0 2\.0 [0m
:s2\.0
s/1\.0/2\.0/gp;ti2\.0

                bs3\.0
:i3\.0
i\
[41m## str2 = 3\.0 [0m\
[41m## 2\.0 3\.0 [0m
:s3\.0
s/2\.0/3\.0/gp;ti3\.0

                bs4\.0
:i4\.0
i\
[41m## str2 = 4\.0 [0m\
[41m## 3\.0 4\.0 [0m
:s4\.0
s/3\.0/4\.0/gp;ti4\.0

文字列がエスケープされていないように見えますが、[これは私の端末が出力に与える影響にすぎません。最終的にすぐに続くcharを食べるようになります\033。 2番目のスクリプトがsedスクリプトを受け取ると、入力は次のようになりますが、\033\[...stdoutに挿入する出力は次のiようになります。\033[...

答え2

これを試みなさい: すべて逃げなさい。すべて.次へ交換\.

str1="$( echo -n $i | sed 's/\./\\\./g' )"  

str2についても同じことを繰り返します。$ j。次に、次のように交換します。

sed "s/$str1/$str2/g"

関連情報