これは私のスクリプトです。
#! /bin/bash
# C-band Edit
dqt='"'
str5="polarization=${dqt}2${dqt}"
for x in {3600..4200} do;
sed -i "/$str5.*$x/s/$x/$((x-600))/" satellites.xml
done
私が望むのは、str5を含むSatellites.xmlのすべての行で、3600から4200の間の数値xをx-600に置き換えることです。しかし、上記のスクリプトで構文エラーが発生します。
ベストアンサー1
x-600
ちょうどあなたがリテラル文字列を意味するのではなく、「3600と4200の間のすべての値から600を引く」という意味だと思いました。この場合、sedではなくPerlを使用してください。
echo "$str5. foo bar 3200 3964 4155 4200 4255" |
perl -p -e "if (/$str5/) {s/3[6789]\d\d|4[01]\d\d|4200/$&-600/eg}"
polarization="2". foo bar 3200 3364 3555 3600 4255
これはPerlの/e
正規表現修飾子を使って右($&-600
)を次のようにします。Perl式で評価されます。。 $&
は一致する値を含むPerl変数なので、$&-600
値から600を引くことを意味します。
これが本当に欲しいものなら、以下に元の答えを残しておきます。また、上記のPerlの回答とまだある程度関連する有用な説明があるからです。
sedと同様に、Perlには-i
内部編集オプションがあるため、Satellites.xmlファイルに直接適用できます。man perlrun
詳細より。
perl -i -p -e "if (/$str5/) {s/3[6789]\d\d|4[01]\d\d|4200/$&-600/eg}" satellites.xml
また、注目すべき点は、XMLファイルで作業するときにおそらくXMLパーサーを使用する必要があることです。幸いなことに、Perlにはいくつかのオプションがあります。XML::パーサーまたはコレクションlibxml-perl。
実際の入力サンプルがないので、変更されたものと変更されていないことを示す例を作成しました。
str5='polarization="2"'
echo "$str5. foo bar 3500 3964 4155 4200 4255" |
sed -e "/$str5/ {s/3[6-9][0-9][0-9]/3-600/g; s/4[01][0-9][0-9]/4-600/g; s/4200/4-600/g}"
polarization="2". foo bar 3500 3-600 4-600 4-600 4255
英語におおよそ翻訳すると、「現在の行に$ str5()が含まれている場合は、polarization="2"
これらの3つの操作をその行に適用してください」。s///
メモ:
3600..4200でループする必要はありません。これにより、すべての内容が変更されます。一つ
sed
600回実行の代わりに実行されます。3600~4200の値を変更したい。つまり、3つの検索と置換操作が必要です。
- ワンピース 3600-3999
- 4000-4199ワンピース
- 1セットで4200ウォンです。
または、
s///
最後の2つのタスクを1つにまとめて2つのタスクとして実行できます。sed -e "/$str5/ { s/3[6-9][0-9][0-9]/3-600/g; s/4[01][0-9][0-9]\|4200/4-600/g }"
正規表現を最適化する他の方法もたくさんありますが、それを行うほど、後で読んで修正するのは難しくなります。
3964
、4155
および4200
変更されました。3500
しかし、そうでは4255
ありません。必要以上に[0-9]
期待どおりに動作しません一部ロケール(範囲に異なる文字があります)具体的には、どのロケールが何であるかはわかりませんが、[0-9]
完全に依存しないほど頻繁に言及されていることを見てください。これが影響する場合は、[[:digit:]]
代わりに使用する[0-9]
か、perl -p
代わりに使用できます(代わりにsed
使用できます)。 rangeにも同様に適用されます。代わりに使用してください。\d
[0-9]
[6-9]
[6789]
$str5
最後に、変数に何を入れるかは非常に注意する必要があります。sed
コマンドに挿入されるので、sedスクリプトを簡単に破ることができます(たとえば、$str5
aを含めると一致が/
壊れます)。/$str5/
sedは、スクリプト部分がシェル変数から来ていることを知らず、実行するように指定されたスクリプトのみを表示します。また、文字列全体は次のようになります。sedによって正規表現として解釈される
\
- これは、正規表現メタ文字がそう.
でなければリテラル文字として解釈されないことを意味します。\.