Wie erhalte ich die 6 Ziffern aus der Mitte eines Dateipfads

Wie erhalte ich die 6 Ziffern aus der Mitte eines Dateipfads

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, awkaber 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.tgzim 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 basenameDienstprogramm gibt Ihnen den Dateinamenteil eines Pfadnamens. In dem von Ihnen gezeigten Beispiel würde dies die Zeichenfolge 201906_load_1_20210623-151602.tar.tgzder Variablen zuweisen. Sie hätten dasselbe nameauch 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, $varder Mdas 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=Cum 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, zshwo 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, $filedie 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 basenameoder 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

201906Ich 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

verwandte Informationen