Wie extrahiert man Zeichen zwischen dem ersten und zweiten Unterstrich von Dateinamen und zählt solche Dateien im Linux-Ordner?

Wie extrahiert man Zeichen zwischen dem ersten und zweiten Unterstrich von Dateinamen und zählt solche Dateien im Linux-Ordner?

Ich möchte Zeichen zwischen dem ersten und zweiten Unterstrich von Dateinamen in einem Ordner extrahieren und die darin vorhandenen Dateien dieses Typs zählen.

Der Ordner enthält Dateien in einem bestimmten Format wie:

2305195303310_ABC_A08_1378408840043.hl7

2305195303310_ABC_A08_1378408840043.hl7
Q37984932T467566261_DEF_R03_1378825633215.hl7
37982442T467537201_DEF_R03_1378823455384.hl7
37982442T467537201_MNO_R03_1378823455384.hl7
2305195303310_ABC_A08_1378408840053.hl7
Q37984932T467566261_DEF_R03_1378825633215.hl7
37982442T467537201_MNO_R03_1378823455384.hl7

Und so weiter…

Die Ausgabe des Skripts sollte mir folgendes Ergebnis liefern:

ABC 3
DEF 3
MNO 2

Antwort1

ls | cut -d_ -f2 | sort | uniq -c

Antwort2

Sie können dies auf die klassische *nix-Art tun, indem Sie kleine Befehle aneinanderreihen. Suchen Sie zunächst die gewünschten Dateien. Dazu können Sie Shell verwenden.Glotzen:

for i in *_*_*; do echo "$i"; done

Dieser Befehl druckt alle Dateien im aktuellen Verzeichnis aus, deren Name zwei Unterstriche enthält. Um die Zeichenfolge zwischen diesen Unterstrichen zu extrahieren, können Sie verwendencut_, und weisen Sie es an, es als Feldtrennzeichen zu verwenden und das zweite Feld auszudrucken:

cut -d '_' -f 2

Wenn Sie den ersten Befehl durch den zweiten leiten, werden die Zeichenfolgen gedruckt, die Sie interessieren, aber es wird auch eine leere Zeile gedruckt, wenn zwischen den Unterstrichen kein Zeichen steht ( foo__barzum Beispiel). Sie können diese herausfiltern, indem Sie verwenden, grep .wodurch nur Zeilen gedruckt werden, die mindestens ein Zeichen enthalten (einschließlich Leerzeichen). Schließlich können Sie zählen, indem Sie die Ausgabe durchsortUnduniq -c.

Alles zusammen ergibt:

$ for i in *_*_*; do echo "$i" | cut -d '_' -f 2 ; done | 
   grep . | sort | uniq -c

  3 ABC
  2 DEF
  1 MNO

Wenn Sie wirklich möchten, dass die Nummer auf der anderen Seite steht, können Sie Folgendes verwenden awk:

$ for i in *_*_*; do echo "$i" | cut -d '_' -f 2 ; done | 
   grep . | sort | uniq -c | awk '{print $2,$1}'

ABC 3
DEF 2
MNO 1

Antwort3

Hier ist eine Möglichkeit, die Aufgabe mit Perl zu erledigen.

perl -aE '/^[^_]+_\K[^_]+/ && $h{$&}++}{say$_," ",$h{$_} for sort keys %h' file
ABC 3
DEF 3
MNO 2

Erläuterung:

perl -aE                # invoque Perl compiler with autosplit lines
/^[^_]+_\K[^_]+/        # match non _ characters after the first _
 &&                     # execute the next command if a match is found
$h{$&}++}               # increment a counter for each match founded
{say$_," ",$h{$_}       # finally print each match and the counter associated
for sort keys %h        # for each sorted matches

verwandte Informationen