4

私はこの質問を投稿し、誰かがこれで答えました

sed '/^void.*{$/!b;:a;/\n}$/bb;$!{N;ba};:b;s/\n/&test1&/;s/\(.*\n\)\(.*\n\)/\1test2\n\2/' file

私はsedとregexに不慣れで、各部分の機能が何であるかを理解することができません。

私は私が理解したことを説明しようとします、そしてあなたたちは不足しているものを埋めることができます。私は文字ごとに行きます

  1. ^void.*{$-これは、で始まり、voidで終わるものすべてを意味します{
  2. /!b;私はこれが何をするのかわかりませんでした。今bはですbranching/そこで何をしているのか
  3. :a;ラベルを作るためのものですa
  4. /\n/再びそこに理解されませんでした
  5. }$それはで終わります}
  6. /bb理解できません
  7. $!ファイルの終わりでない場合は
  8. {N;意味がわかりませんでした。Nはバッファ内の次の行をコピーすることを意味しますが、取得しました{
  9. :b聞き取れませんでした。bは分岐用ですが、そこで何をしているのかわかりません10. s/\n/&test1&/\ nを置き換えると思いますが、よくわかり\ntest1\nません
  10. s/\(.*\n\)\(.*\n\)/\1test2\n\2/これも取得しないでください
4

2 に答える 2

2

;複数のsed式をキャラクターと一緒にチェーンすることができます。それぞれを個別に見てみましょう。

最初の式、/^void.*{$/!bは、区切り記号の間にマッチャー式があり/ます。一致します:

^-行の先頭

void-その後に「void」という文字が続きます

.*-その後に何か

{-続いて左カーリー

$-行の終わりが続きます

その最初の式の修飾子、は!b、マッチャーが一致しない場合、sed評価を中止することを意味します。

式は:aラベルです。これは、分岐と呼ばれるgotoのようなsed機能で使用されます。次の式でラベルがどのように使用されるかを見ていきます。

式は次のよう/\n}$/bbに一致します。

\n-改行

}-右カーリーが続きます

$-行の終わりが続きます

修飾子bbは、一致するものが見つかった場合、ラベルbに「分岐」することを意味します。ラベルbは、後の式でとして定義され:bます。

式は、途中に$!{N;ba}がありますが、1つとして読み取る必要があります。;この場合のカーリーは、一緒に実行されることを意図した一連のコマンドを表しています。

$!-入力の終わりでない場合

{-コマンドのグループを開始します(この場合、2つあります)

N-静かに別の行を読む

ba-ラベルを付けるための分岐

}-コマンドのグループを終了します

次は、式を介して1行:bのシングルを単独で一致させるときにヒットするラベルです。}/\n}$/bb

最後に、かなり標準的な正規表現である2つの代替パターンがあります。前のs式は本質的にを意味しs/find_this/replace_it_with_this/ます。の場合s/\n/&test1&/、次のようになります。

\n-改行を見つける

/-そしてそれを

&-最初の式で一致したもの(この場合は改行)

test1-単語test1

&-そしてまた一致したもの

つまり、基本的には次を。s/\n/&test1&/に置き換えることを意味します。\n\ntest1\n

最後の式も同様ですが、キャプチャと呼ばれるものを導入しています。\(キャプチャを使用すると、すべてを一致させることができますが\)、式の置換部分で使用するために、すべてを保持します。たとえば、。の入力文字列が与えられた場合s/a\(b\)c\(d\)e/\1 \2/に出力されます。例では、、およびは、それぞれエスケープされたparens、およびでキャプチャされたものに置き換えられます。b dabcde\1\2bd

s-これは置換パターンです:

/- 探す

\(\1-そして置換変数に入れます

.- なんでも

*-そしてそれの任意の量

\n-最初に出会った改行を含む

\)-(キャプチャの終了\1

\(\2-そして置換変数に入れます

.- なんでも

*-そしてそれの任意の量

\n-最初に出会った改行を含む

\)-(キャプチャの終了\2

/-そしてそれをすべてに置き換えます

\1-最初にキャプチャされたもの、

test2\n--test2 \ n、

\2-そして2番目にキャプチャされたもの。

于 2013-01-09T03:03:18.610 に答える
2

この学期:

/^void.*{$/!b

一致^void.*{$を意味し、スラッシュは正規表現を囲む正規表現の区切り文字です。だからあなたは得る/^void.*{$/。のように感嘆符が一致式/regex/!の後に続く場合、これは、正規表現がnot一致する場合に次のコマンドを実行することを意味します。次のコマンドはbどちらがブランチです。これは、ラベル名なしで、スクリプトの最後で分岐します。したがって、全体として、この式は一致を試み^void.*{$(つまり、voidで始まり、で終わる行)、一致が失敗した場合にスクリプトの残りの部分を{ジャンプします( )。b!

このこと:

:a;/\n}$/bb;$!{N;ba};

ラベルを開始し、(改行と行上の単一):a;を一致させようとします。これは再び。で囲まれます。一致すると、()を分岐してラベルb(したがって、)になります。これが入力()の終わりでない場合は、行を読み取り、ラベルa()に戻ります。ここでのカーリーペア(つまり)はブロックを作成します。trueの場合、このブロックは全体として実行されます。つまり、より多くの入力があります。つまり、単に次のことを意味します。\n}$}/regex/b/regex/bb$!Nba{commands}$!$!{N;ba}

If not end of input:
begin
   real line
   jump to label a
end
于 2013-01-09T02:13:24.003 に答える