私はsedを学んでいます。 N(次に複数行)を押すまで、すべてがうまくいくようです。練習/理解/コンテキスト目的でこのファイル(guide.txt)を作成しました。ファイルの内容はこんな感じです。
This guide is meant to walk you through a day as a Network
Administrator. By the end, hopefully you will be better
equipped to perform your duties as a Network Administrator
and maybe even enjoy being a Network Administrator that much more.
Network Administrator
Network Administrator
I'm a Network Administrator
したがって、私の目標は、「ネットワーク管理者」のすべてのインスタンスを「システムユーザー」に置き換えることです。 「Network Admin」の最初のインスタンスは改行(\ n)で区切られているため、「Admin」で始まり「Network \ n」で終わる行を前の行に追加するには、複数行の次の演算子(N)が必要です。大丈夫です。しかし、他のすべての「Network Manager」シングルインスタンスもキャプチャしたいと思います。
私の研究では、改行で区切られた文字列に対して1つ、別の文字列に対して1つという2つの代替コマンドが必要であることを知っています。また、最後の行に代替一致と次の複数行が含まれているため、いくつかのジャイブが発生します。だからこれを作りました...
$ sed '
> s/Network Administrator/System User/
> N
> s/Network\nAdministrator/System\nUser/
> ' guide.txt
これにより、次の結果が返されます。
This guide is meant to walk you through a day as a System
User. By the end, hopefully you will be better
equipped to perform your duties as a System User
and maybe even enjoy being a Network Administrator that much more.
System User
Network Administrator
I'm a System User
私は、1行の置換が「ネットワークマネージャ」のすべての「一般的な」インスタンスをキャプチャして「システムユーザー」に置き換えると思いました。 。予期しない結果。
ちょっと迷って、これを見つけました...
$ sed '
> s/Network Administrator/System User/
> N
> s/Network\nAdministrator/System\nUser/
> s/Network Administrator/System User/
> ' guide.txt
さて、見て、私は欲しい結果を得ました...
This guide is meant to walk you through a day as a System
User. By the end, hopefully you will be better
equipped to perform your duties as a System User
and maybe even enjoy being a System User that much more.
System User
System User
I'm a System User
なぜこれはうまくいきますが、元のsedスクリプトは機能しませんか?私は本当にこれを理解したいと思います。
助けてくれてありがとう。
ベストアンサー1
まず、あなたのソリューションが実際には機能しないことに注意してください。次のテストファイルを検討してください。
$ cat test1
Network
Administrator Network
Administrator
次に、次のコマンドを実行します。
$ sed '
s/Network Administrator/System User/
N
s/Network\nAdministrator/System\nUser/
s/Network Administrator/System User/
' test1
System
User Network
Administrator
問題は、コードが最後のコードを置き換えないことですNetwork\nAdministrator
。
このソリューションは動作します。
$ sed ':a; /Network$/{$!{N;ba}}; s/Network\nAdministrator/System\nUser/g; s/Network Administrator/System User/g' test1
System
User System
User
私たちはこれを以下にも適用できますguide.txt
:
$ sed ':a; /Network$/{$!{N;ba}}; s/Network\nAdministrator/System\nUser/g; s/Network Administrator/System User/g' guide.txt
This guide is meant to walk you through a day as a System
User. By the end, hopefully you will be better
equipped to perform your duties as a System User
and maybe even enjoy being a System User that much more.
System User
System User
I'm a System User
重要なことは、要件に合ったものが見つかるまで1行ずつ読み続けることです。いいえ完了Network
したら交換できます。
互換性に関する注意:上記はすべて\n
代替テキストに使用されます。これにはGNU sedが必要です。 BSD/OSX sed では動作しません。
[方へフィリップス.]
複数行バージョン
理解するのに役立つ場合は、同じコマンドを複数行に分けて説明します。
$ sed ':a
/Network$/{
$!{
N
ba
}
}
s/Network\nAdministrator/System\nUser/g
s/Network Administrator/System User/g
' filename
どのように動作しますか?
:a
これでラベルが作成されます
a
。/Network$/{ $!{N;ba} }
行がで終わると、
Network
次のようになります。いいえ最後の行($!
)は次の行(N
)を読み取り、追加し、ラベルa
(ba
)に再分岐します。s/Network\nAdministrator/System\nUser/g
中間改行文字に置き換えてください。
s/Network Administrator/System User/g
中間スペースに置き換えます。
より簡単なソリューション(GNUのみ)
GNU sedを使用する(いいえBSD/OSX)、代替コマンドのみが必要です。
$ sed -zE 's/Network([[:space:]]+)Administrator/System\1User/g' test1
System
User System
User
そしてguide.txt
ファイルへ:
$ sed -zE 's/Network([[:space:]]+)Administrator/System\1User/g' guide.txt
This guide is meant to walk you through a day as a System
User. By the end, hopefully you will be better
equipped to perform your duties as a System User
and maybe even enjoy being a System User that much more.
System User
System User
I'm a System User
この例では、-z
sed に最初の NUL 文字を読み取るように指示します。テキストファイルにはヌル文字を含めることができないため、ファイル全体を一度に読み取る効果があります。これにより、行を失うことを心配することなく置換を実行できます。
ファイルが大きい場合(通常はギガバイトを意味する)、この方法は適切ではありません。大きすぎる場合は、一度に読み取るとシステムRAMに負担がかかる場合があります。
GNUおよびBSD sed用のソリューション
提案通りフィリフォス、ポータブルソリューションは次のとおりです。
sed 'H;1h;$!d;x;s/Network\([[:space:]]\)Administrator/System\1User/g'