staging.inyokaproject.org

awk: Ganze Zeile ausgeben, wenn bestimmtes Merkmal mehr als zweimal auftritt

Status: Gelöst | Ubuntu-Version: Kein Ubuntu
Antworten |

ff

Anmeldungsdatum:
15. Juli 2019

Beiträge: Zähle...

Hallo zusammen,

vielleicht kann mir jemand helfen? Ich möchte eine Datei (später auch mehrere mit Angabe des Dateinamens) per awk durchsuchen. Dabei sollen alle Zeilen ausgegeben werden, bei denen das Merkmal ($18) mehr als zweimal vorkommt.

Bisher habe ich es geschafft die Zeilen, die das gleiche Merkmal besitzen zu zählen. Jetzt ist meine Schwierigkeit all diese Zeilen auch auszugeben.

Hier der Befehl:

BEGIN { FS=OFS=";" } {cnt[$18]++}

END{ for(t in cnt)

{print t,cnt[t]} }

Kann jemand helfen?

Prof._Frink

Anmeldungsdatum:
29. Mai 2010

Beiträge: 1096

Hi,

so sollte es gehen

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
{
    for (i=1;i<=NF;i++)
    {
	if (i != 18 )
	{
	    if ( $i == $18 )
		a[NR] = $0
	}
    }
}

END {

    for (x in a){
	print(a[x])
    }
}

Viele Grüße,

Frink

Prof._Frink

Anmeldungsdatum:
29. Mai 2010

Beiträge: 1096

Hier noch eine Beispielausführung

test.txt:

1 2 3 18 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
18 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19

Aufruf und Ausgabe:

$ awk -f test.awk test.txt
1 2 3 18 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
18 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 1 

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 11278

Wenn ich ff richtig verstehe, will er alle Zeilen, deren Feld 18 in den angegebenen Datei(en) mehrfach mit dem selben Wert vorkommt - ich glaube fast, dass man sich da ohne awk leichter tut:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
#!/usr/bin/env python3
from collections import defaultdict
import fileinput

line_cache = defaultdict(list)
for line in fileinput.input():
    fields = line.rstrip().split(';')
    try:
        line_cache[fields[17]].append(line)  # indices starts at zero
    except IndexError:
        pass

for _, lines in sorted(line_cache.items()):
    if len(lines) > 1:
        for line in lines:
            print(line, end='')

Das Skript akzeptiert auch mehr als eine Datei als Argument, aber um erst mal zu verdeutlichen, was es macht:

$ cat test.csv
1;2;3;4;5;6;7;8;9;10;11;12;13;14;15;16;17;spam;baz;
1;2;3;4;5;6;7;8;9;10;11;12;13;14;15;16;17;foo;bar;
1;2;3;4;5;6;7;8;9;10;11;12;13;14;15;16;17;foo;sploink;
1;2;3;4;5;6;7;8;9;10;11;12;13;14;15;16;17;bar;woosh;
1;2;3;4;5;6;7;8;9;10;11;12;13;14;15;16;17;ham;19;
1;2;3;4;5;6;7;8;9;10;11;12;13;14;15;16;17;foo;19;
1;2;3;4;5;6;7;8;9;10;11;12;13;14;15;16;17;spam;bar;

$ ./multiples_of_field_18.py test.csv
1;2;3;4;5;6;7;8;9;10;11;12;13;14;15;16;17;foo;bar;
1;2;3;4;5;6;7;8;9;10;11;12;13;14;15;16;17;foo;sploink;
1;2;3;4;5;6;7;8;9;10;11;12;13;14;15;16;17;foo;19;
1;2;3;4;5;6;7;8;9;10;11;12;13;14;15;16;17;spam;baz;
1;2;3;4;5;6;7;8;9;10;11;12;13;14;15;16;17;spam;bar; 

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13242

seahawk1986 schrieb:

Wenn ich ff richtig verstehe, will er alle Zeilen, deren Feld 18 in den angegebenen Datei(en) mehrfach mit dem selben Wert vorkommt - ich glaube fast, dass man sich da ohne awk leichter tut:

Och, das geht auch mit awk ganz nett:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
{
  if (++c[$18] == 1)
    l[$18] = $0
  else
    l[$18] = l[$18] "\n" $0
}
END {
  for (i in c)
    if (c[i] > 1) print l[i]
}

Oder, noch etwas knapper

1
2
3
4
5
6
7
{
  l[$18] = (++c[$18] == 1 ? "" : l[$18] "\n") $0
}
END {
  for (i in c)
    if (c[i] > 1) print l[i]
}

ff

(Themenstarter)

Anmeldungsdatum:
15. Juli 2019

Beiträge: 2

Vielen Dank euch allen!

Ihr habt mir wirklich geholfen. Es funktioniert!

Antworten |