
Ich habe einen Dateinamen nach diesem Modell:
1.raw_bank_details_211.trg
2.raw_bank_details_222.trg
Ich muss den cut
Befehl in Unix verwenden und die obige Zeichenfolge ausschneiden, um sie zu erhalten 211
und 222
aus den Zeichenfolgen den Wert wiederzugeben.
Ich habe grep bereits verwendet grep -o -E '[0-9]+'
und brauche eine Alternative dazu.
Antwort1
Sie wären besser dran, wenn Sie ein Standard-Textverarbeitungstool anstelle eines naiven Tools wie verwenden würden cut
.
Hier sind einige Möglichkeiten:
Mit awk
wird das durch _
oder .
getrennte vorletzte Feld abgerufen:
awk -F '[_.]' '{print $(NF-1)}' file.txt
grep
mit PCRE ( -P
):
grep -Po '\d+(?=[^_]*$)' file.txt
-o
erhält nur den passenden Teil\d+
stimmt mit einer oder mehreren Ziffern übereinDer positive Lookahead mit Nullbreite
(?=[^_]*$)
stellt sicher, dass_
bis zum Ende der Zeile kein folgt.
Mit sed
:
sed -E 's/.*_([[:digit:]]+).*/\1/' file.txt
.*_
passt zu allem bis zuletzt_
([[:digit:]]+)
stimmt mit den erforderlichen Ziffern überein und wird in die erfasste Gruppe eingefügt.*
passt zum RestBeim Ersetzen
\1
wird nur die erfasste Gruppe verwendet .
Mit perl
, gleiche Logik wie sed
bei :
perl -pe 's/.*_(\d+).*/$1/' file.txt
Wenn Sie verwenden müssen cut
, tun Sie dies in zwei Schritten: Holen Sie sich zuerst das _
getrennte 4. Feld und dann das .
getrennte 1. Feld:
cut -d_ -f4 file.txt | cut -d. -f1
Dies wird nicht empfohlen, da dies eine Festcodierung der Feldnummern erfordert.
Wenn es ein String wäre, würde ich es mithilfe der Shell-Parametererweiterung machen:
% str='1.raw_bank_details_211.trg'
% str=${str##*_}
% echo "${str%%.*}"
211
Sie können immer noch eine while
Konstruktion verwenden und jede Zeile in eine Variable übernehmen und dies tun, aber das wäre bei einer großen Datei langsam. Alternativ können Sie auch _.
as the verwenden IFS
und stattdessen das fest codierte Feld (wie cut
) abrufen, wenn Sie möchten.
Beispiel:
% cat file.txt
1.raw_bank_details_211.trg
2.raw_bank_details_222.trg
% awk -F '[_.]' '{print $(NF-1)}' file.txt
211
222
% grep -Po '\d+(?=[^_]*$)' file.txt
211
222
% sed -E 's/.*_([[:digit:]]+).*/\1/' file.txt
211
222
% perl -pe 's/.*_(\d+).*/$1/' file.txt
211
222
% cut -d_ -f4 file.txt | cut -d. -f1
211
222
Antwort2
cut
ist dafür das falsche Werkzeug. Um kurze Strings wie Dateinamen zu manipulieren, verwenden Sie nach Möglichkeit die String-Manipulationsfunktionen der Shell. Alle sh-artigen Shells¹ (sh, dash, bash, ksh, zsh, …) verfügen über einige grundlegende String-Manipulationen als Teil der Variablensubstitution. Siehe z. B. dieDash-Handbuchunter „Parametererweiterung“. Sie können das kürzeste/längste Präfix/Suffix entfernen, das einem Muster entspricht.
Sie möchten die letzte Ziffernfolge im Dateinamen, also:
- Bestimmen Sie das nicht numerische Suffix, indem Sie alles bis zur letzten Ziffer entfernen.
- Entfernen Sie dieses Suffix.
- Entfernen Sie alles bis zur letzten Nicht-Ziffer.
filename=1.raw_bank_details_211.trg
suffix="${filename##*[0-9]}"
number="${filename%"$suffix"}"
number="${number##*[!-0-9]}"
¹ Außer einigen Bourne-Shells vor POSIX, aber die sind Ihnen egal.