各コメントブロックの最後のコメント行を除くすべて削除

各コメントブロックの最後のコメント行を除くすべて削除
  • ターゲット:各コメントブロックの最後の行を除くすべてのコメント行を削除します。ファイルがコメントブロックで終わったら、完全に削除します。各コメント行はで始まります#

  • 私が試したコマンド

    sed -z -e 's/#.*\n#/#/g' "${InputP}"
    
  • 入力ファイル

    # Life/Living
    # Life/Passion
    - [Mindfulness.md](file:///home/nikhil/Documents/Git/Life/Passion/PassionSrc/Sports/Yoga/Mindfulness/Mindfulness.md)
    # Life/PersonalManagement
    # Life/Social
    # Linux/AmazingNotes
    # Linux/Backintime
    # Linux/DotFiles
    # Linux/GitScripts
    - [Peaceful.m3u](file:///home/nikhil/Documents/Git/../Mobile/Documents/PortableNotes/PortableNotesSrc/SocialActivity/Music/SongsPlaylist/Data/Peaceful.m3u)
    - [AuxiliaryFiles.sh](file:///home/nikhil/Documents/Git/Linux/GitScripts/GitScriptsSrc/GitInit/GitNew/Src/AuxiliaryFiles.sh)
    # PythonWs/NumericalProgramming
    # PythonWs/Python
    # PythonWs/ScientificComputing
    
  • 期待される出力

    # Life/Passion
    - [Mindfulness.md](file:///home/nikhil/Documents/Git/Life/Passion/PassionSrc/Sports/Yoga/Mindfulness/Mindfulness.md)
    # Linux/GitScripts
    - [Peaceful.m3u](file:///home/nikhil/Documents/Git/../Mobile/Documents/PortableNotes/PortableNotesSrc/SocialActivity/Music/SongsPlaylist/Data/Peaceful.m3u)
    - [AuxiliaryFiles.sh](file:///home/nikhil/Documents/Git/Linux/GitScripts/GitScriptsSrc/GitInit/GitNew/Src/AuxiliaryFiles.sh)
    
  • しかし、私はこの出力を得ます。
    # PythonWs/ScientificComputing
    

この問題を解決する方法を知っている人はいますか?

答え1

問題は.*貪欲なので、をsed -z -e 's/#.*\n#/#/g'含む最初の行から始まる#最後の行まで一致することです#。これは-z、パターン空間のファイル全体を一度に吸収するフラグが原因で発生します(テキストファイルにnullバイトがないと仮定)。

問題を解決するSedスクリプトは次のとおりです。

sed -n '/^#/N;/\n#/D;p' file
  • /^#/N行がで始まると、#次の行がパターンスペースに追加されます。
  • /\n#/Dパターンスペースにnewlineとnewlineが含まれている場合は、#newlineの前のすべてのエントリを削除して新しいループを開始します。
  • pこのコマンドに達すると、パターンスペースが印刷されます。

便利なリンク

答え2

入力から他のコメント行が続くすべてのコメント行を明確に削除したいと思います。sedデフォルトでは正規表現が使用されるため、呼び出しは失敗します。「貪欲な」(つまり、できるだけ消費)、これは変更するのは簡単ではありません。

awkしたがって、指定された目標に基づいたソリューションを追加します。

awk '/^#/{buf=$0;next} {if (buf) {print buf; buf=""}}1' "${InputP}"

または少しコンパクトです。

awk '/^#/{buf=$0;next} buf{print buf; buf=""}1' "${InputP}"
  • これにより、コメント行以外のすべての行が印刷されます(1ルールブロックの外側は、「これまでに変更されたすべての内容を含む現在の行を印刷します」という意味です。この場合は何もありません)。
  • パターンに一致するコメント行が見つかった場合、/^#/内容はバッファに保存されますが、bufまだ印刷されません。コマンドnextは次の実行行に移動するため、残りのコードはコメントアウトされていない行にのみ適用されます。
  • コメント以外の行が表示されると、バッファの内容(存在する場合)が最初に印刷され、実際の行の内容を印刷する前にバッファが空になります(複数の印刷を防ぐため)。

答え3

GNU sedフルルックサウンドモードを使用-zして拡張正規表現を利用すると、-E次のことができます。

$ sed -Ez '
    s/(^|\n)(#[^\n]*\n)+$/\1/
    s/(^|\n)(#[^\n]*\n)+/\1\2/g
' file
  • 末尾のコメントブロックを削除します。
  • すべてのコメントブロックを削除しますが、各コメントブロックの最後の行は保持します。

GNU sedモデルは次のとおりです。

  • sed はファイルを 1 行ずつ読み込みます。-zそれ以外の場合、無効な場合はファイル全体を読み込みます。レコード区切り文字はデフォルトで改行に設定され、ASCIIを使用し\nない限りNULLです。-z\0
  • レコードを読み取ると、後続のレコード区切り文字が切り捨てられ、結果の文字列がパターン空間レジスタに格納されます。パターン空間は、すべてのsedコマンドが実行される場所です。
  • sedそれでは、スクリプトに5つのコマンドがあるとしましょうsed。最初のコマンドはパターンスペースに適用され、パターンスペースを変更し、sed次のコマンドはこの変更されたパターンスペースに適用され、最後のコマンドまで続行されます。その後、無効stdout-nパターンスペースが印刷されます。その後、次のレコードを読み込み、同じsedコマンドシーケンスをパターン空間に適用します。

上記は、スクリプトでフロー制御コマンドが使用されていない場合に有効な非常に簡略化された説明ですsed

はい、そうです。フルルックサウンドモードでは、$パターンスペースが1つしかないため、ファイルの終わりとパターンスペースの終わりを示します。

この構文があると、(regex)+正規表現の欲求が多いため、括弧は最後の正規表現の一致を維持します。

または、次のことができます。

$ sed -e '
    /^#/{h;d;} 
    H;z;x;s/^\n//
' file 

答え4

これは働きます:

perl -ne 'print $x,$_ unless /^#/; $x = /^#/ ? $_ : ""' < infile

投稿した予想結果を取得しました。

編集:説明

  • あなたが望むならそれを考慮してください$x:-)$left_over_line_to_be_printed
  • 最初のステートメントは残りの行をすべて印刷し、現在の行を印刷します(現在の行がヘッダー行ではない場合)。
  • 2番目のステートメントは、「leftover」を表示された最後のヘッダー行または空の文字列に設定します。 (つまり、ヘッダー行ではない場合、「remaining」は最初のステートメントですでに印刷されているため、空の文字列になります。ヘッダー行の場合はその行になります。複数のヘッダー行が一緒にクラスタリングされると、最終的には最後になります)。

関連情報