1

複数の列の一致に基づいて行を破棄したいと思います。列 1 で一致するすべての出現について、対応する列 2 を確認します。列 2 のすべてのエントリが同一である場合にのみ、すべての行を破棄します。列 2 のエントリが 1 つでも異なる場合は、すべての行を保持します。

例:

列 2 のすべてのエントリが Bob と同一であるため、最初の 3 行を破棄します。ただし、列 2 の少なくとも 1 つのエントリが 1 月と異なるため、残りの 4 行はそのままにしておきます。

Bob Blue
Bob Blue
Bob Blue
Jan Red
Jan Red
Jan Green
Jan Red
4

5 に答える 5

4

を使用する 1 つの方法を次に示しGNU awkます。次のように実行します。

awk -f script.awk file.txt{,}

の内容script.awk:

FNR==NR {
    array[$0]++
    next
}

{
    counter = 0
    for (i in array) {
        split(i, holder, FS)
        if (holder[1] == $1) {
            counter++
        }
    }
    if (counter >= 2) {
        print
    }
}

結果:

Jan Red
Jan Red
Jan Green
Jan Red

または、ここにワンライナーがあります:

awk 'FNR==NR { array[$0]++; next } { counter = 0; for (i in array) { split(i, holder, FS); if (holder[1] == $1) counter++ } if (counter >= 2) print } ' file.txt{,}
于 2012-09-22T06:13:41.307 に答える
3

これはうまくいくかもしれません(GNU sedですが):

sed ':a;$!N;/^\(\S*\s\).*\n\1/{s/\n/\x01/;ba};h;x;s/\n.*//;s/^/\x01/;/^\(\x01[^\x01]\+\)\(\1\)\+$/{x;D};s/.//;s/\x01/\n/gp;x;D' file

説明:

  • :aループマーカー
  • $!N最後の行でない限り、改行と次の行をパターン スペース (PS) に追加します。
  • /^\S*\s).*\n\1/{s/\n/\x01/;ba}同じキーで始まるすべての行を 1 行にまとめ、改行を 16 進コードに置き換えます01
  • h現在の PS をホールド スペース (HS) に格納します。
  • xPS と HS を切り替える
  • s/\n.*//追加された最後の行を削除します (これは一致しません)
  • s/^/\x01/HS の先頭に16 進コードを追加01します (これは、一致させるための架空の改行です。
  • /^\(\x01[^\x01]\+\)\(\1\)\+$/{x;D}すべて同じ、つまり例外がない行については、HS を PS に切り替えて、それらの行を削除し、次の反復を開始します。
  • s/.//;s/\x01/\n/gp;x;D'例外がある行は、先頭に追加された 16 進コードを削除し、01他のすべてのそのようなコードを改行に置き換えて、それらの行を出力します。次に、HS を PS に切り替え、最初の改行まで削除して、次の反復を開始します。
于 2012-09-22T11:35:54.950 に答える
0

入力が「test.txt」という名前のテキスト ファイルにある場合は、それを実行できます。

cat test.txt | grep ^`cat test.txt | sort -u | awk 'BEGIN{split("", aux, "");ok="";} {if ($1 in aux){if (length(ok) > 0){ok=ok"\|"$1;}else{ok=$1;}}aux[$1]="";} END{print ok;}' -`

コマンドを理解するためにステップごとに実行するか、私に尋ねることができます (AWK の部分は少し複雑です)。

このようにして、出力は次のようになります。

Jan Red
Jan Red
Jan Green
Jan Red

編集:「|」にバックスラッシュを追加するのを忘れました grep の OR ;-)

于 2012-09-21T17:03:46.720 に答える
0

3 つの簡単な手順:

sort -u temp | nawk '{a[$1]++}END{for(i in a)print i,a[i]}' > temp_file
nawk 'FNR==NR{a[$1]=$2;next}{if(($1 in a) && a[$1]>1)print $0}' temp_file your_file
rm -rf tempfile

これらの手順をシェル スクリプトに組み込んで実行できます。

于 2012-09-24T10:48:21.537 に答える
-1
KEY_STRINGS="`sort file | uniq | awk '{print$1}' | uniq -d`" 
awk -vkeys="$KEY_STRINGS" '{if(keys~/$1/)print$0}' file

このスクリプトの方が理解しやすいと思います。

于 2012-09-21T17:35:53.567 に答える