私の入力ファイルは次のとおりです。
START
line1
line2
line3
END
START
line11
line22
line33
END
私のスクリプトは次のように出力したいと思います。
START line1 line2 line3 END
START line11 line22 line33 END
助けてください。
答え1
使用awk
:
$ awk '{printf "%s", $0 (($0 == "END") ? ORS : OFS)}'
START
から まで行を書くには、END
次のようにします。
$ awk '($0 =]"START"),($0 == "END"){printf "%s%s",$0, ($0=="END" ? ORS : OFS)}'
それ以外の場合は、次のコマンドを使用できますSTART
。END
$ awk '($0 == "START"){a="";} {a = a $0 (($0 == "END") ? "" : OFS)} ($0 == "END"){print a}'
答え2
複数文字にはGNU awkを使用し、RS
次RT
の例に示すように、データに常に完全でネストされず、重複しないSTART-ENDブロックがあるとします。
$ awk -v RS='\nEND\n' -F'\n' '{$0=$0 RT; $1=$1} 1' file
START line1 line2 line3 END
START line11 line22 line33 END
START-ENDブロックの外側に行を追加できる場合は、代わりに次のようにします。
$ awk -v RS='\nEND\n' -F'\n' 'RT{$0=gensub(/.*\n(START\n)/,"\\1",1) RT; $1=$1; print}' file
START line1 line2 line3 END
START line11 line22 line33 END
または awk を使用してください。
$ awk '
$0 == "START" { f=1; rec=$0; next }
f { rec=rec OFS $0; if ( $0 == "END" ) { print rec; f=0 } }
' file
START line1 line2 line3 END
START line11 line22 line33 END
入れ子になった、重なっている、または不完全なSTART-ENDブロックがあり、上記で必要に応じて機能しない場合は、これらの要件を表示するように質問を編集する必要があります。
答え3
使用sed
:
$ sed -n -e '/^START$/ { h; d; }' -e H -e '/^END$/ { g; y/\n/ /; p; }' file
START line1 line2 line3 END
START line11 line22 line33 END
スクリプトsed
はコメントとともに見事に印刷されます。
# Save each "START" line in the hold space and skip to the next line.
/^START$/ {
h
d
}
# Append all non-"START" lines to the hold space.
H
# On an "END" line, get the hold space, convert newlines to spaces, and print.
/^END$/ {
g
y/\n/ /
p
}
これは、「START」行と「END」行の範囲が重複せず、「END」と「START」の間に追加データがないと仮定する。
答え4
使用幸せ(以前のPerl_6)
END
あるレコードと次のレコードの間の中間行(たとえば、および間)を削除するには START
:
~$ raku -ne 'S/ <!after END> $/ / andthen do if /^START/ fff s/^END$/END\n/ {.print};' file
または:
~$ raku -ne 'S/ <!after END> $/ / andthen print ($_ if /^START/ fff s/^END$/END\n/) ;' file
上記はRakuプログラミング言語でコーディングされた答えです。つまり、-ne
コマンドラインフラグは、自動印刷なしで入力ファイルでコードを1行ずつ実行するために使用されます。単語で終わらない各行にS///
「big-S」置換演算子を使用し(否定的な振り返り)、スペースを追加します。この手順を使用すると、間にスペースを含む行を簡単にリンクできます(注:@Kusalanandaがコメントに投稿したものと同様の回答を得るために使用されます)。<!after END> $
END
\t
引き続き$_
テーマ変数の再読み込みを使用してくださいandthen
。 Rakuのsedに似た/START/ fff /STOP/
「トリプルf」トリガ演算子を使用して、目的のセンチネルライン間のラインをキャプチャできます。書式トリックでは、実際に同じトリガー演算子のセンチネル行をs/^END$/END\n/
置き換えて、その後に改行を追加できます。END
fff
\n
END
最後に、出力は、print
独自の改行文字を追加せずに上記の空白/改行形式を保持するRakuの単純な演算子を介して行われます。
入力例:
START
line1
line2
line3
END
test
START
line11
line22
line33
END
出力例(中央の行を削除):
START line1 line2 line3 END
START line11 line22 line33 END
さて、どうすれば中間線を守ることができますか?簡単です。fff
Rakuの「whatever-star」を使用してすべての出発線を許可するようにトリガー演算子を変更するだけです。*
以下を参照してください。
~$ raku -ne 'S/ <!after END> $/ / andthen do if * fff s/^END$/END\n/ {.print};' file
START line1 line2 line3 END
test START line11 line22 line33 END
#OR
~$ raku -ne 'S/ <!after END> $/ / andthen print ($_ if * fff s/^END$/END\n/);' file
START line1 line2 line3 END
test START line11 line22 line33 END
https://docs.raku.org/syntax/S%2F%2F%2F%20Non-destructive%20replacement
https://docs.raku.org/routine/fff
https://docs.raku.org/routine/andthen
https://raku.org