次の形式のファイルがあります。
A 485C72F95C72E15C EXTERNAL
B CC32480A3247F84A SYSTEM
C EC2A63F12A63B76C EXTERNAL
変数「letter」の値を使用して最初の列に文字を指定し、2番目の列の値を変数「id」に指定した値に置き換えます。 3番目の列は、どんな場合でも異なる場合も一致する場合もあります。 1列目と2列目には、スペースや特殊文字は含まれません。
sed
を使用しようとしましたが、私のsed-fuは強くありません。私はこれを思いつきました:
letter=A
id=MYNEWIDSTRING
sed "/$letter /s/[^ ]*/$id/2"
出力は次のとおりです。
A MYNEWIDSTRING EXTERNAL
B MYNEWIDSTRING SYSTEM
C EC2A63F12A63B76C EXTERNAL
Idは2行で置き換えられます。これは、元のid文字列の最後で「A」が一致したためと思われます。
sed -i
を使用してファイルをインプレース編集することは知っていますが、コマンドはまだ少し危険なので、まだ編集していません。
どこで間違っていますか、または別の方法を使用する必要がありますか?
A
が最初の文字の場合にのみ一致するように、アンカーします(^
は行の先頭です):
$ letter=A; id=MYNEWIDSTRING; sed "/^$letter /s/[^ ]*/$id/2" file
A MYNEWIDSTRING EXTERNAL
B CC32480A3247F84A SYSTEM
C EC2A63F12A63B76C EXTERNAL
ところで、変数をsed
に渡したいが、強力な引用符が必要な場合は、変数の二重引用符を追加しながら引用符のオンとオフを切り替えることができます-lyいですが、おそらくベストプラクティス:
sed '/^'"$letter"' /s/[^ ]*/'"$id"'/2'
structured dataを扱うときはいつでも、awk
ではなくPerl
またはsed
に到達します。
例えば
awk -v letter="A" -v id="MYNEWIDSTRING" '$1 == letter {$2=id}1' file
A MYNEWIDSTRING EXTERNAL
B CC32480A3247F84A SYSTEM
C EC2A63F12A63B76C EXTERNAL
または
Perl -alne '
BEGIN{$letter = shift; $id = shift;}
print join " ", $F[0], $F[0] eq $letter ? $id : $F[1], @F[2..$#F]
' 'A' 'MYNEWIDSTRING' file
GNU awkの新しいバージョンには、-i
(--in-place
)フラグがあります。その他では、明示的な一時ファイルを使用する必要があります。 Perlには、-i
が必要です。