4

最初のフィールドが重複している行のみを印刷しようとしています。たとえば、次のようなデータから:

1 abcd
1 efgh
2 ijkl
3 mnop
4 qrst
4 uvwx

印刷する必要があります:

1 abcd
1 efgh
4 qrst
4 uvwx

(FYI - 私のデータでは、最初のフィールドが常に 1 文字であるとは限りません)

4

5 に答える 5

5
awk 'FNR==NR{a[$1]++;next}(a[$1] > 1)' ./infile ./infile

はい、入力と同じファイルを 2 回指定します。現在のレコードが uniq かどうかは事前にわからないため、最初のパスに基づいて配列を構築し、2 番目のパスで複数回$1見たレコードのみを出力します。$1

ファイルを1回通過するだけでそれを行う方法があると確信していますが、それらが「クリーン」になるとは思えません

説明

  1. FNR==NRawk: これは、 が最初のファイルを読み取っている場合にのみ当てはまります。基本的に、表示されたレコードの総数 (NR) と現在のファイルの入力レコード (FNR) をテストします。
  2. a[$1]++: 連想配列を作成します。whoキーは最初のフィールド ( $1) であり、who の値は表示されるたびに 1 ずつ増加します。
  3. next: これに達した場合、残りのスクリプトを無視し、新しい入力レコードからやり直します
  4. (a[$1] > 1)これは の 2 回目のパスでのみ評価され、複数回見た./infile最初のフィールド ( ) のレコードのみが出力されます。$1本質的に、それはの省略形ですif(a[$1] > 1){print $0}

コンセプトの証明

$ cat ./infile
1 abcd
1 efgh
2 ijkl
3 mnop
4 qrst
4 uvwx

$ awk 'FNR==NR{a[$1]++;next}(a[$1] > 1)' ./infile ./infile
1 abcd
1 efgh
4 qrst
4 uvwx
于 2011-02-25T23:33:04.230 に答える
1

入力がすでに最初のフィールドでグループ化されていると仮定して、必要なことを行う awk コードを次に示します (required のようuniqに):

BEGIN {f = ""; l = ""}
{
  if ($1 == f) {
    if (l != "") {
      print l
      l = ""
    }
    print $0
  } else {
    f = $1
    l = $0
  }
}

このコードでfは、 はフィールド 1 の前の値でlあり、グループの最初の行です (既に出力されている場合は空です)。

于 2011-02-25T23:38:36.417 に答える
1
BEGIN { IDLE = 0; DUP = 1; state = IDLE }

{ 
  if (state == IDLE) {
    if($1 == lasttime) {
       state = DUP
       print lastline
    } else state = IDLE
  } else {
    if($1 != lasttime)
        state = IDLE
  }
  if (state == DUP)
    print $0
  lasttime = $1
  lastline = $0
}
于 2011-02-25T23:41:16.737 に答える
0

質問に示されているように、順序付けされた入力を想定します。

awk '$1 == prev {if (prevline) print prevline; print $0; prevline=""; next} {prev = $1; prevline=$0}' inputfile

ファイルは 1 回だけ読み取る必要があります。

于 2011-02-26T01:33:07.137 に答える