14

「TITLE」と「DATA」で始まる行が入れ替わったテキストファイルがありますが、「TITLE」で始まる行が重複している場合があります。

タイトル何か
データいくつかのデータ
タイトル何か他
のデータいくつかの他のデータ
タイトルいくつかのより多くの
タイトル追加情報
データいくつかのより多くのデータ

'TITLE'で始まる重複行を検出し、そのような各ペアの最初の行のみを保持できるようにしたいと思います。
これらをキャプチャするための正規表現は、これを1行のコマンド^TITLE.*\n^TITLE.*\nに組み込んで2行目を削除し、ファイルの残りの部分を出力するようにしたいと思いましたが、これを理解できませんでした。perlbashsedawk

4

5 に答える 5

7

Perl ソリューション:

perl -ne 'print unless $t and /^TITLE/; $t = /^TITLE/'

$t前の行が変数の TITLE であったかどうかを記憶しています。

于 2013-03-15T11:14:53.013 に答える
7

GNU sed でできる 1 つの方法を次に示します。

sed -r 'N; /(TITLE)[^\n]*\n\1/ s/\n.*//; P; D' infile
  • N2 番目の行をパターン スペースに入れます。
  • 一致は、両方の行が で始まるかどうかをテストしTITLEます。
  • その場合、2 行目は削除されます。
  • P; Dパターンスペースの最初の行を印刷して削除します。

出力:

TITLE something
DATA some data
TITLE something else
DATA some other data
TITLE some more
DATA some more data

編集 - 任意の回数の繰り返しを処理

コメントでNikina Reklawyksが指摘したように、上記のソリューションは で始まる 2 つの連続する行でのみ機能しTITLE、任意の回数の繰り返しを処理するには、次のように単純なループを追加できます。

sed -r ':a; N; /(TITLE)[^\n]*\n\1/ s/\n.*//; ta; P; D' infile

このtaステートメントは、成功した場合に sed を:aラベルにジャンプさs///せます。

それを行う別の方法は、uniqからのコマンドを使用することcoreutilsです。これはそれほど柔軟ではありませんが、それでもこの場合はうまく機能します:

uniq -w5 infile 
于 2013-03-15T11:31:02.020 に答える
4

一方通行:

awk '$1!=p{print;p=$1}' file
于 2013-03-15T11:12:51.547 に答える
3

TITLE と DATA の 2 つのフィールドで構成されるレコードがあり、2 番目のフィールドが欠落している場合はレコードを削除したいと思われます。しかし、それはあなたが質問で尋ねたことではありません。したがって、ここにあなたが尋ねたことを行う1つの方法があります:

awk '/^TITLE/&&!t{t=$0} /^DATA/&&t{print t;print;t=""}' inputfile

ここでの考え方は、変数が表示されたときに TITLE を設定し、まだタイトル付きのセットがなく、DATA が表示されたときにのみ出力するというものです。あなたの質問を正しく読んでいれば、これはあなたが提供した入力データに対して機能します。出力は次のとおりです。

TITLE something
DATA some data
TITLE something else
DATA some other data
TITLE some more
DATA some more data

ご覧のとおり、データセットの最後の TITLE 行が削除されました。

そして、awkでこれを行う別の方法があります...

awk '/^TITLE/&&t{next} t=0; /^TITLE/{t=1} 1' inputfile

この例では、最初の式が設定されている場合、タイトルをスキップしtます。2 番目の式は設定を解除しtます。3 番目の式はタイトルの if を設定し、最後の式 ( 1) は行を出力します。もちろん、最初の式の行をスキップした場合、最後の 3 つの式は実行されません。上記と同じ出力が生成され、わざわざ を確認する必要はありません/^DATA/

最後に、これは最小のコードですが、最も奇妙なロジックです。

awk '/^DATA/ || !t; {t=/^TITLE/}' inputfile

すべてのデータ行、またはt設定されていない行を出力し、効果的tにブール値に設定して、次の行の評価に影響を与えます。これを csh または tcsh で実行している場合は、感嘆符に注意してください。これらのシェルでは、感嘆符をエスケープする必要がある場合があります。

于 2013-03-15T11:36:55.853 に答える
2

このワンライナーを試してください:

 awk '/^TITLE/&&f{next;} {if ($0~/^TITLE/)f=1;else f=0}1' file

出力:

TITLE something
DATA some data
TITLE something else
DATA some other data
TITLE some more
DATA some more data
于 2013-03-15T11:12:34.783 に答える