オリジナルファイル
claudio
antonio
claudio
michele
次のような結果を得るために、「claudio」の最初の項目を「claudia」に変更したいと思います。
claudia
antonio
claudio
michele
私は以下を試しました:
sed -e '1,/claudio/s/claudio/claudia/' nomi
上記のコマンドはグローバル置換を実行します(すべての「claudio」エントリを置き換えます)。なぜ?
答え1
GNUを使用している場合は、以下をsed
試してください。
sed -e '0,/claudio/ s/claudio/claudia/' nomi
sed
まで終了範囲の正規表現チェックを開始しません。後ろに範囲を開始する行です。
~からman sed
(POSIXマンページ、強調鉱山):
2つのアドレスを持つ編集コマンドは、最初のアドレスと一致する最初のパターンスペースから包含範囲を選択する必要があります。Next パターン空間2番目と一致します。
ただし、このアドレスは標準ではなく、他の実装ではサポートされていないGNU拡張0
です。sed
sed
使用awk
作業範囲はawk
あなたの期待に合致します。
$ awk 'NR==1,/claudio/{sub(/claudio/, "claudia")} 1' nomi
claudia
antonio
claudio
michele
説明する:
NR==1,/claudio/
これは、行1から始めて最初の項目で終わる範囲です
claudio
。sub(/claudio/, "claudia")
この代替コマンドは、範囲内にあるときに実行されます。
1
これはawkの印刷ラインの秘密の略語です。
答え2
GNUの新しいバージョンはsed
この-z
オプションをサポートしています。
通常、sedは行末(改行またはキャリッジリターン)まで文字列を読み取り、行を読み取ります。
バージョン 4.2.2 の GNU バージョン sed には、代わりに "NULL" 文字を使用する機能が追加されました。これは、レコード区切り文字としてNULLを使用するファイルがある場合に便利です。一部のGNUユーティリティは、「find . -print0」や「grep -lZ」など、新しい行の代わりにNULLを使用する出力を生成できます。
sed
別の行で作業したい場合は、このオプションを使用できます。
echo 'claudio
antonio
claudio
michele' | sed -z 's/claudio/claudia/'
返品
claudia
antonio
claudio
michele
答え3
まとめる
GNU構文:
sed '/claudio/{s//claudia/;:p;n;bp}' file
または(置換したい単語を一度だけ使用する:
sed '/\(claudi\)o/{s//\1a/;:p;n;bp}' file
またはPOSIX構文を使用して:
sed -e '/claudio/{s//claudia/;:p' -e 'n;bp' -e '}' file
すべてのsed、プロセスに適用可能ただ最初のものを見つけると、最初の行にあっclaudio
てもできるだけ多くの行が必要になり、1つのclaudio
正規表現文字列だけが使用されるため、短くなります。
詳細
変更のみ一行あなたはする必要があります選ぶ1行だけです。
1,/claudio/
(質問から)以下を使用して選択します。
- 最初の行から始める(無条件)
- 到着Next文字列を含む行
claudio
。
$ cat file
claudio 1
antonio 2
claudio 3
michele 4
$ sed -n '1,/claudio/{p}' file
claudio 1
antonio 2
claudio 3
選ぶどの行を含めるには、claudio
次を使用します。
$ sed -n `/claudio/{p}` file
claudio 1
claudio 3
そしてのみ選択最初 claudio
ファイルで次を使用します。
sed -n '/claudio/{p;q}' file
claudio 1
その後、その行でのみ変更できます。
sed '/claudio/{s/claudio/claudia/;q}' file
claudia 1
これだけ変わるよ最初2 つ以上があっても、その行で正規表現の一致が発生します。最初正規表現に一致する行です。
もちろん、/claudio/
正規表現は次のように単純化できます。
$ sed '/claudio/{s//claudia/;q}' file
claudia 1
次に、欠けている唯一のものは、変更されていない他のすべての行を印刷することです。
sed '/claudio/{s//claudia/;:p;n;bp}' file
答え4
awk
フラグを使用して、交換が完了したことを確認できます。そうでない場合は続けます。
$ awk '!f && /claudio/ {$0="claudia"; f=1}1' file
claudia
antonio
claudio
michele