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

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}'

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.


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.


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

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.


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

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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.