
Ich habe einen Dateipfadnamen wie
/dbfs/mnt/dlg2stage/foldername/backupname/201906_load_1_20210623-151602.tar.tgz
Ich versuche, nur die sechsstelligen 201906
Ziffern abzurufen und auszudrucken. Ich habe es versucht sed
, awk
aber es hat nicht geklappt.
Antwort1
Vorausgesetzt, es handelt sich dabei um tatsächlich auf Ihrem System vorhandene Dateien, können Sie mithilfe einer Shell-Schleife problemlos den Teil vor dem ersten _
in den Dateinamen aller passenden Dateien *_*.tar.tgz
im Verzeichnis extrahieren /dbfs/mnt/dlg2stage/foldername/backupname
:
for pathname in /dbfs/mnt/dlg2stage/foldername/backupname/*_*.tar.tgz; do
name=$( basename "$pathname" )
printf '%s\n' "${name%%_*}"
done
Das basename
Dienstprogramm gibt Ihnen den Dateinamenteil eines Pfadnamens. In dem von Ihnen gezeigten Beispiel würde dies die Zeichenfolge 201906_load_1_20210623-151602.tar.tgz
der Variablen zuweisen. Sie hätten dasselbe name
auch tun können (diese Parametererweiterung entfernt den ersten Abschnitt der Zeichenfolge in , bis einschließlich dem letzten ).name=${pathname##*/}
$pathname
/
Die Parametererweiterung ${name%%_*}
würde dazu führen, dass die längste übereinstimmende Teilzeichenfolge _*
aus dem Wert entfernt wird $name
. Im gezeigten Beispiel würde dies das erste _
Zeichen und alles rechts davon entfernen, sodass die Teilzeichenfolge übrig bleibt 201906
, die dann mit ausgegeben wird printf
.
Antwort2
Mit zsh
:
file=/dbfs/mnt/dlg2stage/foldername/backupname/201906_load_1_20210623-151602.tar.tgz
set -o extendedglob # for (#c6)
first_6_digits_of_file_tail=${(M)${file:t}[0-9](#c6)}
Wohin ${file:t}
führt derSchwanzder Datei (ihr Basisname) ${(M)var#pattern}
gibt den Teil am Anfang zurück, $var
der M
das Muster anfügt.
POSIXly, Sie können Folgendes verwenden:
first_6_digits_of_file_tail=$(
LC_ALL=C expr "/$file" : '.*/\([0-9]\{6\}\)[^/]*/*$'
)
LC_ALL=C
um die Ländereinstellung des Benutzers zu ignorieren und alle Bytes als Zeichen zu betrachten (die 128 zuerst gemäß ASCII auf den meisten Systemen, einschließlich / und 0123456789 Ziffern), sodass .
garantiert [^/]
Bytes übereinstimmen und [0-9]
nur 0123456789 eingeschlossen ist. Es sind keine Ziffern, zsh
wo Bereiche auf Codepunkten basieren und zsh jedes Byte, das nicht anderweitig Teil gültiger Zeichen ist, als wäre es ein Zeichen.
Vorangestellt wird /
, um Probleme bei Werten zu vermeiden, $file
die mit Operatoren beginnen -
oder wie solche aussehen expr
, und auch um zu garantieren, dass die Zeichenfolgen mindestens einen Operator enthalten, /
wie vom regulären Ausdruck erwartet.
Wir lassen keine /
s nach dem /XXXXXX
„except“ ganz am Ende zu, um dasselbe Verhalten zu erzielen wie Lösungen, die basename
oder zshs verwenden $file:t
, bei denen der Basisname von /foo/bar/
oder /foo/bar////
ist bar
.
Beachten Sie, dass ein falscher bzw. fehlgeschlagener Beendigungsstatus zurückgegeben wird, wenn keine Übereinstimmung vorliegt, aber auch, wenn die 6-stellige Ziffernfolge die Zahl 0 darstellt (wie in /path/to/000000_whatever
).
Antwort3
201906
Ich denke, Sie möchten nur den angegebenen Pfad drucken . In diesem Beispiel lauten diese sechs Ziffern:die ersten sechs Ziffern, vor denen ein Schrägstrich steht.
Ich setze den Pfad in eine Variable, um den Befehl leichter lesbar zu machen:
% path_str='/dbfs/mnt/dlg2stage/foldername/backupname/201906_load_1_20210623-151602.tar.tgz'
% echo $path_str | sed 's/.*\/\([0-9]\{6\}\).*/\1/'
201906
Hier ist, wie ich dieses Match und den Ersatz aufgebaut habe insed:
\/[0-9]\{6\}
: entspricht einem Schrägstrich und 6 Ziffern\/\([0-9]\{6\}\)
: ist das gleiche, aber jetzt in einerErfassungsgruppeoderUnterausdruck(der Schrägstrich gehört nicht zur Erfassungsgruppe).*\/\([0-9]\{6\}\).*
: passt zu allem davor und danach, also ...die ganze Linie\1
: Wenn die ganze Zeile übereinstimmt, verwenden Sie die Referenz für dieErste(und einzige) Capture-Gruppe, um die ganze Zeile durch nur die ersten 6 Ziffern zu ersetzen