Bashから追加の行を削除する最速の方法、または文字列が#の場合は最後の行

Bashから追加の行を削除する最速の方法、または文字列が#の場合は最後の行

bash次のような場合は、スクリプトの最後に生成されたファイルを整理するためのエレガントな方法を探しています。

  1. 削除する行の下の行の最初の文字は次のとおりです。# または
  2. #ファイルの最後の行の最初の文字です。

ファイルは次のとおりです(参照行番号はに[]ありますが、いいえファイル自体から):

[1] # foo
[2] bar1
[3] bar2
[4] bar3
[5] # foob
[6] #ar
[7] ar1
[8] ar2
[9] ar3
[10] #

上記の例では、5行と10行を削除したいと思います。で始まる#行の後に、で始まる行が続くことを望まないし、#ファイルの最後の行がで始まることも望ましくありません#

編集:期待される出力:

[1] # foo
[2] bar1
[3] bar2
[4] bar3
[5] #ar
[6] ar1
[7] ar2
[8] ar3

bash行って自分で教える素晴らしいsed構文と混同されますが、awkここへの答えになりそうです。

答え1

考えるあなたが望むもの

sed -e '${/^#/d}' -e '$!N;/^#.*\n#/D' -e 'P;D' file
  • ${/^#/d}アドレスの最後の行が$一致した場合は^#削除します。

  • $!N...P;Dスクロールを維持する2行のバッファ

  • /^#.*\n#/D#パターンの先頭と改行の後にある場合は、改行を削除して新しいループを開始します。

答え2

sed要件は、指示どおりにコーディングできます。

sed -e '
  /^#/!b
  $d;N
  /\n#/D
' file
  • 興味のないすべての行は標準出力に送信されます。これは印刷を意味します。/^#/!b

  • 興味深い行は次のように始まります。#

  • 興味深いことに、最後の行が削除されました。$d

  • 無意味な行は、コードの2番目のsed行には現れません。

  • 関心のある行がファイルの最後の行ではない場合は、次の行を追加します。N

  • 次の行も興味深い場合は、前の行を削除し、既存のパターンスペースを使用してsedスクリプトの一番上に移動します。 /\n#/D

使用されるさまざまなsedコマンドの詳細については、sedのマニュアルを参照してください。

答え3

sedマルチライン技術が利用可能です。

sed -E 'N;s/(^#.*)(#.*)/\2/;${s/(.*)(#.*)/\1/}' file

Nnewlineこのコマンドは、パターンスペースにaと次の行を追加します。

パターンがある行の場合は、^#.*#.*最初の行を削除します。

${}最後の行の場合、パターンが.*#.*一致することを確認し、最後の部分を削除します。

答え4

sed -n '/^#/{:a;h;n;//b a;H;g;};p' file

オプションは-n自動印刷を無効にし、行はジョブpに従って印刷されます。/^#/{ ... }– で始まる行から#一連の操作を実行します。:a...b a次のループを設定します。

  • hホールド空間(つまり、現在の行をバッファに保存)をパターン空間に置き換えます。
  • nパターン空間に入力の次の行を読み込みます(または入力しなくても終了します)。
  • //b a- パターンスペースが一致すると、b牧草地に移動します。の空の正規表現はの略語です。:a/^#/sedapply the last used regex

ループが完了したら:H;g- 現在のパターンスペースをホールドスペースに追加し、パターンスペースをホールドスペースに置き換えます。p最後に、ループや行以外のすべての結果を印刷します#

#結果:行セットの最後の行のみが印刷され、#最後の行は印刷されません。

# foo
bar1
bar2
bar3
#ar
ar1
ar2
ar3

関連情報