Filtern von Daten basierend auf Trennzeichen in der Shell

Filtern von Daten basierend auf Trennzeichen in der Shell

Ich habe eine Datei mit folgenden Daten:

"google1|yoo|dummy|yes|wow|/" + VARIABLE + "/"
"google2|hub|lab|dummy|yes|/" + VARIABLE + "/"
"google3|short|lab|yoo|/" + VARIABLE + "/"
"google4|hello|good-guy|bad-girl|lol|dummy|/" + VARIABLE + "/"
"google5|good-guy|a4-123|yoo|/" + VARIABLE + "/"
"google6|bad-girl|b4-124|hub|/" + VARIABLE + "/"

Jetzt möchte ich eine Liste von Zeichenfolgen zwischen den Trennzeichen „|“ (Pipe) erhalten.

Die Ausgabe sollte wie folgt aussehen:

yoo
dummy
yes
wow
hub
hello
good-guy
bad-girl
a4-123
b4-124
dummy
lol
short
lab

Grundsätzlich möchte ich eindeutige Werte aus der Liste der Zeichenfolgen nach dem Trennzeichenfilter haben. Ich habe versucht, awk als

awk -F"|" '{gsub(/\).*/,"",$2);print $2}' file

Aber ich erhalte falsche Daten.

Antwort1

Wenn Sie grepdie pcreOption haben:

$ grep -oP '\|\K[^|]+(?=\|)' ip.txt | sort -u
a4-123
b4-124
bad-girl
dummy
good-guy
hello
hub
lab
lol
short
wow
yes
yoo
  • -onur passende Muster drucken
  • -PVerwenden Sie den regulären PCRE-Ausdruck
  • \|\Kpositiver Lookbehind, um zu sehen, ob |vor unserem zu extrahierenden String etwas vorhanden ist
    • ebenso (?=\|)positiver Lookahead, um zu sehen, ob |nach unserem zu extrahierenden String noch etwas folgt
  • [^|]+zu extrahierende Zeichenfolge - negieren Sie einfach |und erhalten Sie ein oder mehrere solcher Zeichen
  • sort -uum einen eindeutigen Wert zu erhalten

Wenn Sie die Reihenfolge beibehalten möchten, in der diese Zeichenfolgen gefunden werden:

$ grep -oP '\|\K[^|]+(?=\|)' ip.txt | awk '!seen[$0]++'
yoo
dummy
yes
wow
hub
lab
short
hello
good-guy
bad-girl
lol
a4-123
b4-124

Antwort2

Wenn Ihnen die Reihenfolge egal ist, können Sie einen Perl-Hash verwenden, um die Eindeutigkeit sicherzustellen, z. B.

$ perl -lne '$h{$_}++ for /(?<=\|).*?(?=\|)/g; END{print for keys %h}' file
short
b4-124
lol
yes
bad-girl
lab
yoo
good-guy
hub
dummy
hello
a4-123
wow

SehenErstellen eines Hashs mit Regex-Übereinstimmungen in Perl

Antwort3

wie wäre es mit folgendem?

cut file -d'|' -f2,3,4 | tr '|' '\n'

Der obige Befehl druckt eine feste Anzahl von Spalten (3). Wenn Sie eine variable Anzahl von Spalten bis zum ersten Vorkommen von drucken möchten /, können Sie etwas wie Folgendes verwenden:

cut -d'/' -f1 file | cut  -d'|' -f2- | tr '|' '\n'

Antwort4

Ihre Ausgabe enthält „Dummy“-Wiederholungen. Das ist, was ich mit dem folgenden Skript bekomme -

   awk -f f1.awk /tmp/f1
    short
    hub
    wow
    hello
    a4-123
    b4-124
    yes
    yoo
    lol
    bad-girl
    good-guy
    lab
    dummy

    cat f1.awk 
    {
      n=split($1,a,"|")

      for(i=2; i<n; i++) {
        arr[a[i]] = a[i] 
      } 
    }   
    END{
      for (var in arr) 
        print(var)  
    }

verwandte Informationen