このsedスクリプトがどのように機能するのか理解できません。
echo -e "Line #1\n\n\n\nLine #2\n\n\nLine #3" | sed '1s/^$//p;/./,/^$/!d'
cat -s
「しかし、いくつかの質問があります」など、繰り返される空白行を抑制します。
- 何のために
1s/^$//p
?私が理解したところによると、最初の行が空であっても何もしません。 /./,/^$/
最初の「いいね!」以前のみ一致し、一致しませんか?^$
Line #1\n\n
Line #1\n\n\n
- sedの基本的な範囲は欲張っていませんか?
質問3を明確にするために、次のテストを試しました。
echo -e "Line #1\n\n\n\nLine #2\n\n\nLine #3" | sed -n '/#/,/#/p'
結果:
Line #1
Line #2
Line #3
(だから貪欲だ)
しかし、私が試したとき:
echo -e "Line #1\n\n\n\nLine #2\n\n\nLine #3" | sed -n '/#1/,/#/p'
結果:
Line #1
Line #2
(もう欲はないと思います)
答え1
1s/^$//p
最初の行が空の場合、最初の行を印刷します。
/./,/^$/
空でない最初の行の行を、見つかった最初の空の行と一致させます。正規表現修飾子の意味で欲はありません。sed
ファイルを介して前方に見たり逆追跡する方法がないため、終了パターンの最初の一致で停止する必要があります。
終了行の後、開始行の検索が再開されるため、空でない次の行は範囲を再開します。実際には、範囲は空でない連続ラインと次の最初の空のラインと一致します。
範囲が使用されるため、/./,/^$/!d
一致しないすべての行が削除されます。これには最初の行(空の場合)が含まれ、これが最初のルールがこれを明示的に印刷する理由です。
ルールがない1s/^$//p
場合は、実際に「重複」でない場合でも、最初の行が空の場合は削除されます。
$ echo $'\nfoo' | sed '1s/^$//p;/./,/^$/!d'
foo
$ echo $'\nfoo' | sed '/./,/^$/!d'
foo
$
テストでは、/#/,/#/
同じパターンで開始して終了するため、範囲が若干異なります。Line #1
開始パターンと一致するため(中央の空白行が印刷されます)、終了パターンと一致しLine #2
(次の空白行はそうではありません)、Line #3
範囲が再開されます。
もう一つは開始パターンですが、/#1/
入力で一度だけ見つかります。
答え2
ilkkachuはsed文字列の最初の部分のためのあまり明確な必要性と「!」文字が実際に繰り返される空の行である一致しない部分を削除するという事実を含む、コマンドのさまざまな側面に対処する良い答えを提供しました。
しかし、これはより簡単なオプションがある場合は奇妙なアプローチです。社会的習慣またはユニーク書くことができる。