sed を使用:
#!/bin/sed -nf
P
: loop
s/\s.*//
N
/\([^\n][^\n]*\)\n\1/ b loop
D
まず、-n
フラグを sed に渡して、指定した内容のみを出力する必要があります。
最初の行は常に印刷され、必要なときにのみこの行を実行するように sed を強制するため、「P」コマンドで行を印刷することから始めます。
次に、ループを実行します。「:」コマンド (この場合、ラベルに「loop」という名前を付けます) を使用して開始ラベルを使用してループを定義し、必要に応じて、「b」コマンド (または「t」テスト) を使用してこのラベルに戻ります。指図)。このループは非常に単純です。
- 最初のフィールド以外をすべて削除します (最初のスペース文字とそれに続くすべてのものを何も置き換えません)。
- 次の行を追加します (改行文字が含まれます)
- 新しい行が分離したフィールドで始まるかどうかを確認します。これは、キャプチャを使用して行います。キャプチャは、一致した入力が特別な「変数」に格納される「サブマッチ」として定義され、存在するキャプチャの順序に従って番号が付けられます。バックスラッシュでエスケープされた括弧を使用してキャプチャを指定します (で始まり、
\(
で終わります\)
)。この場合、改行文字ではないすべての文字 (つまり[^\n]
) を行末まで一致させます。これは、改行以外の文字の少なくとも 1 つとそれに続く任意の文字列を照合することによって行われます。これにより、改行の前に空の文字列が一致するのを防ぎます。キャプチャの後、特別な変数を使用して、改行文字とそれに続くキャプチャの結果を照合します。\1
、その最初のキャプチャで一致した入力が含まれています。これが成功すると、最初のフィールドを繰り返す行があるので、「b」分岐コマンドでループの先頭に戻ります。
- ループを終了すると、最初のフィールドが異なる行が見つかったので、入力行を準備して、スクリプトの先頭に戻る必要があります。これは、"D" delete-first-line-and-restart-script コマンドで実行できます。
これは 1 行に短縮できます (「ループ」ラベルの名前を「a」に変更したことに注意してください)。
sed -e 'P;:a;s/\s.*//;N;/\([^\n][^\n]*\)\n\1/ba;D'