sedコマンド「n」と「b」の違いは何ですか?

sedコマンド「n」と「b」の違いは何ですか?

bラベルは許可しますが、nラベルは許可せず、ラベルなしで使用するには、...aなしで渡された引数bの最後に(少なくとも1行)ラベルを配置する必要があるという明白な構文点に加えて、ラベルとanは同じことをするようです。-ebn

これは本当ですか?それとも私が認識しなかった微妙な違いはありますか?どんな条件で彼らは同じことをし、どんな条件では同じことをしませんか。

答え1

両方の例は同じで、nただb。出力が異なることがわかります。

$ echo $'1\n2\n3' | sed 's/./AA/; n; s/./BB/'
AA
BB
AA
$ echo $'1\n2\n3' | sed 's/./AA/; b; s/./BB/'
AA
AA
AA

bコマンドの最後に分岐します。 n残りのコマンドを実行し続けます。したがって、についてはb置き換えはs/./BB/行われません。使用する場合は、n1行ずつフィルタリングして実行します。

(上記のコマンドはGNU sedを使用して実行されました。BSD / OSX sedの場合は、OPで指摘されているように、コード形式に少しの変更が必要です。)

答え2

まあ...
ranchbコマンドは次のとおりです。

[2addr]b[label]
    Branch to :label. If label is not specified, branch to the end of the script.

外部nコマンド:

[2addr]n
    If auto-print is not disabled, print the pattern space, then, regardless,
    replace the pattern space with the next line of input. If no next line of
    input is available, branch to the end of the script.

ここでの主な違いは次のとおりです。

b無条件にスクリプトの最後に分岐
nし、入力がなくなった場合にのみスクリプトの最後に分岐します。

入力が次のようになるとします。

fdue
four
four
fdue
four

f私はに置き換えたいのですが、他のすべての行ではなくt一致する行でのみ置き換えたいと思います。一つの方法はfourui

sed '/four/{s/f/t/;b;};s/u/i/' infile

出力は予想通りです

fdie
tour
tour
fdie
tour

nそれでは、代わりに使用するときに何が起こるのかを見てみましょうb

fdie
tour
foir
fdie
tour

2行目の一致は、単純な理由でスクリプトの一番上に戻らないようにfour編集されました。代わりに、それ以降の行を処理するコマンドは意図したものだとは考えません。ただし、最後の行では最初の置換のみが実行されるため、後続のコマンドは実行されなくなります。foirtournsnsn

要約すると、次の条件が満たされると、これら2つのコマンドは機能的に同じです。

  • スクリプトは入力の最後の行(今後実行n)または
  • いずれにせよ、導入された次の行は1よりn前のコマンドで編集しないでください(つまり、次の行はリンクされたアドレスではありません)。nb

n現在のパターン空間を印刷して次の行を取得するのは本当ですが、bそれだけでも同じ効果があります。スクリプトの最後に分岐することは、自動的に印刷することを意味し(sedcallを使用しない-n限りn印刷されません)、次に自動的に次の行を読みます。私が言ったように、最大​​の違いはnスクリプトの最後にジャンプできないことです(そしてスクリプトの一番上に戻ることはできません)。sed残りのコマンドを実行するだけです。最後の行にない場合)。



1私が言ったように、スクリプトの一番上に戻ることができないため、このコマンドは実行されません。n残りのコマンドは、発生しない行を編集できます。

答え3

"branch"コマンド(b)は編集スクリプトから事前定義されたラベルに分岐するか、ラベルがない場合はスクリプトの最後に分岐しますが、 "next"コマンド(n)は入力の次の行を読み取ります。また、「next」コマンドは、出力抑制が使用されていない限り、次の行(通常読み取った行)を読み取る前に現在のパターンスペースを出力します-n

2つの異なる操作を実行する2つの異なる編集コマンド。 "next"コマンドはスクリプトの終わりまで分岐を引き起こさず、 "branch"コマンドは現在のパターンスペースを出力したり、独自の新しい行を読み取ったりしません。

簡単な例(GNUを使用sed):

$ cat lines
1
2
3
4
5

$ gsed -n '3{n;p;p;}' lines
4
4

3行目の場合、スクリプトは次の行を読み取り、2回印刷します。 4行目は2回印刷されます。

$ gsed -n '3{b;p;p;}' lines

スクリプトが "print"( p) コマンドに分岐するため、出力は生成されません。

なしで実行する場合-n

$ gsed '3{n;p;p;}' lines
1
2
3
4
4
4
5

3行目はnスクリプトのコマンド出力です。 4行目は3回出力され、次の行をp読み取った後、スクリプトから2回、基本コマンドとして1回出力されます。 np

$ gsed '3{b;p;p;}' lines
1
2
3
4
5

"branch"コマンドはスクリプトでこれらの2行をバイパスするため、この行はデフォルトのコマンドpによって出力されます。p

結論として:n次の行をロードし、次の命令処理を続行して、指定された分岐b(名前が指定されている場合)またはスクリプトの最後に移動します。どちらの場合も、sed がスクリプトの終わりに達すると、残りの入力は通常どおりスクリプトの先頭から処理されます。

関連情報