Wie drucke ich alle Zeilen einer Datei mit doppelten Werten in einer bestimmten Spalte?

7

Bei einer Datei wie dieser:

1,768,12,46576457,7898
1,123,435,134,146
2,345,6756856,12312,1311
5,234,567465,12341,1341
1,3245,4356345,2442,13
9,423,2342,121,463
9,989,342,121,1212

Ich möchte alle Zeilen (im Bash-Terminal) so auflisten, dass der Wert in Spalte 1 mindestens zweimal erscheint (in Spalte 1). Das Ergebnis sollte sein

1,768,12,46576457,7898
1,123,435,134,146
1,3245,4356345,2442,13
9,423,2342,121,463
9,989,342,121,1212
Bob
quelle

Antworten:

11

Um zu vermeiden, dass die gesamte Datei im Speicher gespeichert wird, haben Sie folgende Möglichkeiten:

awk -F , '
  !count[$1]++ {save[$1] = $0; next}
  count[$1] == 2 {
    print save[$1]
    delete save[$1]
  }
  {print}'
Stéphane Chazelas
quelle
4

Perl-Lösung:

perl -F, -ane ' $h{ $F[0] } .= $_
                }{
                $h{$_} =~ tr/\n// >= 2 and print $h{$_} for keys %h
              ' < input-file
  • -n liest die Eingabe zeilenweise
  • -ateilt jede Zeile auf -F, dh Komma, in das @FArray.
  • Zeilen werden in dem %hdurch das erste Feld ( $F[0]) eingegebenen Hash gespeichert . Sie sind miteinander verkettet ( .=).
  • Am Ende der Datei ("Eskimo-Begrüßung" }{) durchlaufen wir die Tasten und zählen die Anzahl der Zeilenumbrüche (mit dem trOperator). Wenn es mindestens 2 ist, drucken wir die gespeicherten Zeilen.

Sie können die Ausgabe füttern, | sort -nwenn die erste Spalte numerisch sortiert werden soll.

Achtung: Wenn die letzte Zeile nicht in einer neuen Zeile enden würde, würde ihre Gruppe ihre Größe angeben - 1. Sie können chompjede Zeile und die neuen Zeilen selbst hinzufügen, um sie zu beheben, oder ein Array von Zeilenarrays anstelle eines Array von Zeichenfolgen verwenden.

Choroba
quelle
1

Mit awk (GNU awk für mehrdimensionale Arrays)

gawk -F, '
    { line[NR] = $0; count[$1]++; found[$1][NR] = 1}
    END {
        for (id in count)
            if (count[id] > 1)
                for (nr in found[id]) 
                    print line[nr]
    }
' file

Die Reihenfolge der Ausgabe stimmt möglicherweise nicht mit der Eingabedatei überein.

Glenn Jackman
quelle
Ich glaube, das ist GNU AWK 4. Frühere Versionen behandeln (gefälschte) mehrdimensionale Arrays unterschiedlich.
Bis auf weiteres angehalten.
1

Ein weiterer awkAnsatz zum Entfernen eindeutiger Zeilen basierend auf Spalte 1 (oder zum Zurückgeben doppelter Zeilen basierend auf Spalte 1)

awk -F, 'NR==FNR{s[$1]++;next} (s[$1]>1)' infile infile
αғsнιη
quelle
0
for i in $(cat given | cut -d, -f1)
do
  linect=$(grep ^"${i}," given | wc -l)
  if [ ${linect} -gt 1 ]
  then
    grep ^"${i}," given >> result
  fi
done
sort result |uniq > desiredoutput

Solange die Felder durch Komma getrennt sind und Sie nur in Spalte 1 und Spalte 1 nach Duplikaten suchen, sollte dies funktionieren.

MelBurslan
quelle
kann geschrieben werden alsgrep -f <(cut -d, -f1 file | sort | uniq -c | awk '$1>1 {print "^"$2","}') file
Glenn Jackman
Eine der vielen Möglichkeiten, wie es geschrieben werden kann, ist in meinem Beispiel. Ich wollte es nur verständlicher machen.
MelBurslan
2
verstanden. Nur um es effizienter zu machen: Ein Grep-Anruf im Vergleich zu 2n-Anrufen.
Glenn Jackman
@glennjackman Ich mag deine Lösung. Es scheint jedoch nicht mit großen Dateien zu funktionieren. Ich bin mir nicht sicher, ob das ein Problem mit grep ist.
Bob
0

Eine andere Variante (wo test.txtist Ihre Eingabedatei):

FILE=test.txt ; for n in $(cat ${FILE} | awk -F"," '{count[$1]++} END {for (i in count) print i":"count[i]}'|grep -v ':1'|awk -F: '{print $1}');do grep ^${n} ${FILE} ;done
paulp
quelle
Das ist fast das Hässlichste, was ich je gesehen habe.
Bis auf weiteres angehalten.
0

Verwenden von Python 3:

#!/usr/bin/env python3
import sys
from collections import defaultdict

column_delimiter = sys.argv[1]
column = int(sys.argv[2]) - 1

records = defaultdict(list)
for l in sys.stdin:
    l = l.rstrip('\n')
    r = l.split(column_delimiter)
    records[r[column]].append(l)

for ll in records.values():
    if len(ll) > 1:
        print(*ll, sep='\n')

Verwendungszweck:

python3 duplicate-columns.py COLUMN-DELIMITER COLUMN

Beispiel:

python3 duplicate-columns.py ',' 1 < data.csv
David Foerster
quelle