ファイル内の文字列を別の文字列に置き換えたいのですが、両方と同じ.
特殊文字(この場合は文字)があります。1.0
2.0
現在使用されているコマンドは次のとおりです。
sed -i 's/1\.0/2\.0/g' /home/user1/file1.txt
1.0
andが2.0
変数andに保存された場合はどう$i
なりますか$j
?i
価値はどこにありますか1.0
?j
価値は何で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
すべてのデータ処理を実行できます。sed
2つが呼び出されても、それぞれが一度だけ呼び出されます。
実行すると、結果は次のようになります。
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"