
前の質問を検索しましたが、質問が出た後に追加されました。前に必要です:
world world
world world
world world
したがって、sedは特定のテキストのN番目の発生の先頭に "hello"を追加する必要があります。この場合、4番目の世界に以下を追加します。
world world
world hello world
world world
答え1
sedを使用する必要がある場合は、次のことを試すことができますが、すでに説明したように、sedパスは不安定になります。
sed -e '
H;1h;g
s/world/HELLO &/4;tn
$!d;:n;n;bn
' yourfile
答え2
sed
操作に誤ったツールです。使用awk
またはperl
交換してください。例えば
$ perl -pe 's/world/++$i == 4 ? "hello world" : $&/ge' input.txt
world world
world hello world
world world
これは/e
、代替演算子の代替部分がs///
文字列として解釈されず、Perlコードで実行されるようにするperl regex修飾子を使用することに注意してください。
コードは各一致に対して++$i == 4 ? "hello world" : $&
カウンタ変数()を事前にインクリメントし$i
、4に等しい場合は一致を「hello world」に置き換え、それ以外の場合は一致を独自の項目($&
)に置き換えます。
答え3
「sedを使用してください」と言ったことはわかりますが、現実の世界でこのようなことをする必要がある場合は、すべてのUnixシステムのすべてのシェルでawkを使用してフルワード文字列比較を実行する方法は次のとおりです。パターンに一致するテキストを見つける方法これが重要な理由):
$ awk -v n=4 '{
for (i=1;i<=NF;i++) {
if ( ($i == "world") && (++cnt == n) ) {
$i = "hello " $i
}
}
print
}' file
world world
world hello world
world world
入力内容が次のようになると想像してみてください。
$ cat file
google.com mygoole.comedy
googleycom google.com
google.com google.com
google.com
そして、4番目の項目(現在の入力の最後の項目)の前に「hello」を入れようとしています。上記のawkスクリプトを使用すると、次のように変更され$i=="world"
ます$i=="google.com"
。
$ cat file
awk -v n=4 '{
for (i=1;i<=NF;i++) {
if ( ($i == "google.com") && (++cnt == n) ) {
$i = "hello " $i
}
}
print
}' file
google.com mygoole.comedy
googleycom google.com
google.com hello google.com
ここで、sedスクリプトを使用して同じことを試してみてください(特にPOSIX構文のみを使用し、GNU拡張を使用しない場合)。これで、sedスクリプトをin&out
代替テキストとして使用すると、より多くの問題が見つかります。hello
答え4
sed 'H;1h;$!d;x;s/world/hello &/4'