foo
I love
Stack Exchange
bar
Some junk
lines
foo
Welcome to the
world of
Bash
bar
foo
Elon Musk
rocks
bar
はい、ファイルの末尾には補足項目はありません。foo
希望の出力は
I love Stack Exchange
Welcome to the world of Bash
Elon Musk rocks
^foo
だから、私との間^bar
にあるすべての改行文字を削除してください。^foo
end of file
bar
答え1
そしてawk
:
awk '
$0 == "foo" {if (sep) print ""; sep = ""; inside = 1; next}
$0 == "bar" {inside = 0; next}
inside {printf "%s", sep $0; sep = " "}
END {if (sep) print ""}'
foo
最初の単語がある行を一致させるには;で始まる行を一致させるには、(の省略形)を$0 == "foo"
置き換えます。$1 == "foo"
foo
/^foo/
$0 ~ /^foo/
答え2
Perlが救出に来る!
perl -ne '
if ($e = /^foo$/ .. /^bar$/) {
if ($e =~ /E/) { print "\n" }
else {
chomp;
print " " if $e > 2;
print if $e > 1;
}
}' -- input.txt
-n
入力を1行ずつ読みます。..
ブロック内の各行の相対行番号を返す範囲演算子。最後の行E0
が追加されました。
答え3
次のようにすることもできます。
a) これは、POSIX-sed
予約された領域に中間範囲行 (!/foo/ および !/bar/) を格納する互換コードです。
sed -e '
/foo/,/bar/!d
/foo/d
/bar/!{H;$!d;}
s/.*//;x;s/^\n//;y/\n/ /
' input-file.txt
b) そしてPerl
図に示すように
perl -lne '
next unless /foo/ ... /bar/;
push(@A, $_),next if !/foo/ && !/bar/ && !eof;
push(@A, $_) if !/foo/ && !/bar/ && eof;
print join " ", splice @A if /bar/ || !/foo/ && eof;
' input-file.txt
説明する:
- 興味のない行や範囲外の行をスキップします。範囲は、含む行で始まり、で終わると定義され
/foo/
、/bar/
両方とも別の行に表示されます。 - 範囲内にある場合は、現在ある行に基づいて個々の操作を実行します。
- /foo/、/bar/、eof以外の行の場合:その行を配列に保存します
@A
。保存が完了したら、次のレコード(eof以外)を読み取るために戻ります。 - 範囲の終わり、つまり、または次の
/bar/
収集サイクルを準備するためにコンテンツを印刷して空にすることをeof
実行します。@A