47

入力について考えてみましょう。

=sec1=
some-line
some-other-line

foo
bar=baz

=sec2=
c=baz

= sec1 =のみを処理したい場合は、たとえば、次の方法でセクションをコメントアウトできます。

sed -e '/=sec1=/,/=[a-z]*=/s:^:#:' < input

... よくほとんど。

これにより、 「=sec1="」と「=sec2=」の行を含む行がコメント化され、結果は次のようになります。

#=sec1=
#some-line
#some-other-line
#
#foo
#bar=baz
#
#=sec2=
c=baz

私の質問は次のとおりです。sedの/START/、/ END /範囲から開始行と終了行を除外する最も簡単な方法は何ですか?

多くの場合、「s :::」の爪を改良することでこの特定のケースで解決策が得られることを私は知っていますが、私はここで一般的な解決策を求めています。

Sed-はじめにとチュートリアル」で、ブルース・バーネットは次のように書いています。「コマンドを制限する方法を後で説明しますが、指定されたパターンを含む行は含まれません。」しかし、彼が実際に表示する場所を見つけることができませんでした。これ。

EricPementが編集した「USEFULONE-LINESCRIPTS FOR SED 」では、包括的な例しか見つかりませんでした。

# print section of file between two regular expressions (inclusive)
sed -n '/Iowa/,/Montana/p'             # case sensitive
4

5 に答える 5

40

これでうまくいくはずです:

sed -e '/=sec1=/,/=sec2=/ { /=sec1=/b; /=sec2=/b; s/^/#/ }' < input

これはsec1とsec2の間で包括的に一致し、コマンドの最初と最後の行をスキップしbます。これにより、sec1とsec2(排他的)の間に目的の行が残り、sコマンドはコメント記号を追加します。

残念ながら、区切り文字を一致させるために正規表現を繰り返す必要があります。私の知る限り、これを行うためのより良い方法はありません。少なくとも、正規表現は2回使用されていても、クリーンに保つことができます。

これは、SED FAQから採用されています。RE1とRE2の間のすべての回線(回線自体を除く)に対処するにはどうすればよいですか?

于 2009-07-27T10:38:50.007 に答える
14

範囲外の行には興味がないが、質問からのアイオワ/モンタナの例の非包括的バリアントが必要な場合(これが私をここに連れてきたものです)、「最初と最後を除いて」と書くことができます2番目のsedを使用すると、「行の一致」句を簡単に実行できます。

sed -n '/PATTERN1/,/PATTERN2/p' < input | sed '1d;$d'

個人的には、これは同等のものよりもわずかに明確です(大きなファイルでは遅くなりますが)

sed -n '1,/PATTERN1/d;/PATTERN2/q;p' < input

于 2011-03-07T10:48:23.677 に答える
7

別の方法は

sed '/begin/,/end/ {
       /begin/n
       /end/ !p
     }'

/begin/n->「開始」パターンのある行をスキップします
/end/ !p->「終了」パターンのないすべての行を印刷します

BruceBarnettのsedチュートリアルhttp://www.grymoire.com/Unix/Sed.html#toc-uh-35aから引用

于 2012-07-12T11:10:54.067 に答える
2

私が使用した:

sed '/begin/,/end/{/begin\|end/!p}'

これにより、パターン間のすべての行が検索され、パターンを含まないものがすべて印刷されます。

于 2017-08-15T14:15:32.297 に答える
1

awkを使用することもできます

awk '/sec1/{f=1;print;next}f && !/sec2/{ $0="#"$0}/sec2/{f=0}1' file
于 2009-07-27T10:53:43.503 に答える