パターンを変数に置き換える

パターンを変数に置き換える

$new他の変数に使用して保存したファイルの3行を置き換える必要がある変数には、3行の数字が格納されています。私の考えでは。しかし、エラーが発生します。grep$oldsed "s/$old/$new/g" input > output

sed: 1: "s/\( 28.47969107 0. ...": unterminated substitute pattern

私の入力ファイルは次のとおりです。

scale
 1.000
primitive lattice vectors
    28.47969107  0.00000000  0.00000000
   0.00000000 28.47969107  0.00000000
   0.00000000  0.00000000 28.47969107
grid dimensions
  100 100 100

$oldは善です

28.47969107 0.00000000 0.00000000 0.00000000 28.47969107 0.00000000 0.00000000 0.00000000 28.47969107

$new形式は以前と同じで数字のみが異なります。

答え1

sed -e "/$old/i$new" -e "/$old/{N;N;d}" input > output

どこ

  • $old28.47969107最初の行でも最初の行でもかまいません。28.47969107 0.00000000 0.00000000
  • $new形態にならなければならない28.47969107 0.00000000 0.00000000\n0.00000000 28.47969107 0.00000000\n0.00000000 0.00000000 28.47969107

-z変数からエスケープする別の方法(最新のGNU sed(バージョン> 4.2.1)とオプションがある場合):newline

sed -z "s/$(printf "%b" "$old"|sed '$!s/$/\\/')/$(printf "%b" "$new"|sed 's/$/\\/')/" input > output

または、スクリプト割り当て機能で置き換えると

end_esc(){ printf "%b" "$@"|sed '$!s/$/\\/' ; }
sed -z "s/$(end_esc $old)/$(end_esc $new)/" input > output

答え2

まず、サンプル文字列を定義してみましょうnew

$ new=$'1 2 3\n4 5 6\n7 8 9'

それでは、次の3行を削除しprimitive lattice vectorsて次に置き換えますnew

$ awk -v "new=$new" 'f==1{print new} f{f--;next} {print} /primitive/{f=3}' input
scale
 1.000
primitive lattice vectors
1 2 3
4 5 6
7 8 9
grid dimensions
  100 100 100

答え3

sed -e '$!N;$b' -e "/\n.*\n/!N;s/$old/$new/;t" -e P\;D

上記のコードは動作しますが、問題があります。の改行文字$oldはで表されなければならず\n、 の改行文字$newの前にはバックスラッシュが来なければなりません\。値の改行により問題が発生します。たとえば、拡張後:

sed 's/24.0000000001
.000000000000
.0000000000/...'

...動作しません。それは終了していない正規表現- 願いより?

代わりに:

old='num\nnum\nnum'
new='num\
num\
num'

...それがすべてです。

何らかの理由で変数をエスケープするのに問題がある場合は、次のようにします。

(  set -f; IFS='
'; printf '%s\\n' / .* '/!N;s/'$old
   printf '%s\\\n' */$new"/;t$IFS#"
)| sed -e '$N;$b' -f - -e P\;D input > output

ただし、これは両方の変数に空白行があってはなりません。これは簡単ではないかもしれません。

答え4

sed s/"$old"/"$new"/g私のために働く

関連情報