Ich habe eine Reihe von Dateien im folgenden Format:
2014-11-19.8.ext
2014-11-26.1.ext
2014-11-26.2.blah.ext
2014-11-26_3.ext
2014-11-26.4.stuff_here.ext
2014-12-03.1. could be anything.ext
2014-12-032b.ext
2014-11-26 613 adva.ext
Mein Ziel ist es, die gesamte Liste der Dateien zu durchlaufen und die Datumsformatierung zu übernehmen YYYY-MM-DD
und diese in einer Variablen im Format YYYYMMDD
für die weitere Verarbeitung zu speichern (in meinem Fall wird sie in einen touch
Befehl verschoben ).
Normalerweise würde ich also gegen diesen regulären Ausdruck antreten: (\d{4})-(\d{2})-(\d{2}).*
Und dann benutze $1$2$3
, um mein gewünschtes Muster zu erhalten, aber ich bin mir nicht sicher, wie ich das in bash
/ machen soll zsh
.
Wie kann dies innerhalb eines Shell-Skripts als solches erfolgen?
bash
shell-script
shell
zsh
ylluminate
quelle
quelle
YYYY
undMM
, aber dann schnappst du dir einfach den Rest mit${f:8}
, wenn ich lieber einfach greifenDD
und wegwerfen möchte.*
(alles danachDD
).Antworten:
Mit Parameter Expansion
${f:0:4}
bedeutet 4 Zeichen ab Index0
undf
ist Variablennameecho "$d"
deinen Code ersetzenquelle
5:2
beginnt in diesem Fall also mit dem 1. Strich, schließt ihn aber nicht ein.8:2
beginnt am 2. Strich und enthält ihn nicht. Sehr interessant und toll zu wissen.0
startet Index ... also ist der erste-
Index4
...Um jede Datei im aktuellen Verzeichnis zu durchlaufen und ihre Dateinamen mit dem gewünschten Muster zu vergleichen, legen Sie eine Variable fest, die die Datumsangaben enthält
Dies nutzt die
[[
Fähigkeit von bash , reguläre Ausdrücke zu verwenden, um die Datumsangaben in das Array BASH_REMATCH zu platzieren.quelle
Sie können dies interaktiv tun, indem Sie Folgendes verwenden
GNU sed
:Für mehrere Dateien (wenn sie sich im selben Verzeichnis befinden und keine anderen berücksichtigten Dateien im Verzeichnis):
quelle
touch
). IchHier ist eine
zsh
Möglichkeit, dies ohne Schleifen zu tun:[0-9](#c4)
bedeutet, dass jede Ziffer viermal wiederholt wird$1
-$2
Siehe zuvor verwendete Klammern-n
verhindert die Ausführung (nur Drucke), entfernen Sie dieses Flag, wenn Sie mit dem Ergebnis zufrieden sindDa
zsh
sich um das Globbing kümmert, sollten alle Eckfälle (Leerzeichen, Sonderzeichen usw.) automatisch berücksichtigt werden.quelle
Wenn Sie auf GNU Coreutils sind, haben Sie Folgendes:
Jedoch:
Die Aufgabe ist also viel einfacher: Extrahieren Sie die ersten zehn Zeichen jedes
YYYY-MM-DDetc
Dateinamens, um das Datum selbst zu erhalten, und übergeben Sie es danndate
zur Neuformatierung an.Wenn wir uns jedoch auf GNU Coreutils befinden, können wir den
date
Befehl überspringen, da ertouch
genau die gleiche--date=STRING
Option hat.Aber warum hacken diese zehn Zeichen auf tragbare Weise mit POSIX, wenn wir uns darauf verlassen
touch
, von GNU Coreutils zu stammen?quelle
touch
derYYYYMMDD
nur Format benötigte , als der-t
Parameter ausgegeben wurde ...-t
erfordert [[cc] yy] mmddhhmm [.ss] - was nicht dasselbe ist, wie Sie geschrieben haben, obwohl keine andere Interpunktion als möglicherweise ein Punkt weggelassen wird -, sondern in der GNU-Version (wie klar angegeben)--date
(oder-d
) ist anders.Versuchen Sie die Mustersubstitution:
Parameter ist der Basisname der Datei. Muster ist ein Strich. In diesem / - Muster global ersetzen. Zeichenfolge ist leer, da Sie die Bindestriche löschen möchten.
Vorsichtsmaßnahme: Ich habe das mit dem Fall von Leerzeichen in der Erweiterung nicht zum Laufen gebracht.
quelle
DD
im Muster. Das Ziel ist es, JJJJMMTT zu extrahieren, um es in einemtouch
Befehl zu verwenden, nachdem das richtige Muster erhalten wurde, da ich den Dateinamen selbst intakt lassen und einfach die Datierung für den Zeitstempel des Dateisystems herausziehen werde. Könnte die obigen Kommentare von @Sundeep sehen, soweit sie nahe beieinander liegen, aber ich folge bis jetzt nicht der tatsächlichen Logik in der Parametererweiterungskette.for f in *.ext; do d="${f%%.*}"; echo "${d//-}"; done
(entfernen Sie zuerst die längste nachfolgende Zeichenfolge und dann die Bindestriche).