0

いくつかの名前ブロックの上に名前とコメントが含まれるファイルを解析したかったのです。次のようなファイルがある場合:

Art
Boat
Road
Tree
Street

# Blah
Star
Car
Sun

Sock

# Comm1
# Comm2
Stop
Stick
# Comm
Stock
Dock

そして、「S」で始まるすべての名前とそれに対応するコメントを抽出するような方法でこのファイルを解析したかったのです。対応するコメントは、直前の空白が検出されるまでの直前のコメントブロック(1行以上のコメント)です。また、空白または別のコメントブロックが検出されるまで、1つのコメントブロックがそれに続くすべてのエントリに適用されます。したがって、上記の入力の出力は次のようになります。

**Name      Comments**

Street
Star        # Blah
Sun         # Blah
Sock
Stop        # Comm1 # Comm2
Stick       # Comm1 # Comm2
Stock       # Comm

誰かがこれを行うための良い方法を提案できますか(できればシェルを使用して)?本当にありがたいです。ありがとう!

PS:私の説明がはっきりしない場合は、申し訳ありませんが、これはまだ新しいことです。

4

2 に答える 2

1

これは、仕事をする少し洗練されていない awk です。

awk '/^$/ {ca=""; cp=""} /^#/ {ca=ca " " $0} /^S/ && ca {cp=ca; ca=""} /^S/ {print $0 " " cp}' < input.txt > output.txt

caコメント アキュムレータとコメント印刷バッファ の2 つのストアがありますcp

  1. 空白行が検出されるたびに、両方がクリアされます。
  2. コメント行が検出されると、コメント アキュムレータに追加されます。
  3. S で始まる行が検出され、コメント アキュムレータに内容がある場合、コメント印刷バッファはコメント アキュムレータにあるものに設定され、後者はクリアされます。
  4. S で始まる行が検出されると、その行が出力され、続いてコメント印刷バッファーにあるものがすべて出力されます。

これを行うにはおそらくもっと洗練された方法があり、これには間違いなく問題があります (たとえば、コメントなしで行末にスペースを入れるなど)。

于 2012-08-01T01:01:51.157 に答える
1

空白行に空白が含まれていないと仮定します。

sed -n '/^#/H; /^S/{G; y/\n/ /; p}; /^$/h' input

最初のコマンド ( /^#/H) は、現在の行 (コメント) を保留スペースに追加します。次のコマンドは、ホールド スペース (蓄積されたすべてのコメントを含む) を現在のバッファーに追加し、すべての改行を 1 つのスペースに置き換えてから、その行を出力します。最後のコマンドは、空白行が検出されるたびにホールド スペースをクリアします。

編集(ブラディブラに感謝)

上記は、先行する空白行なしで新しいコメント ブロックが検出された場合、アキュムレータを正しくリセットしません。これは醜いですが、その理由は次のとおりです。

sed -n '/^#/{h; bk}; :j /^S/{G; y/\n/ /; p}; /^$/h; d; :k n; /^#/{ H; bk}; bj;' input
于 2012-08-01T22:38:35.700 に答える