Ich habe einen Ordner, der Ordner enthält, die Dateien der Form enthalten
resultstatsDF_iris_2017-05-26--21-33-35-437096_methodnr-2_percentage-0.05_seed-0.wcr
Ich möchte das Datum und die Uhrzeit für jedes dieser Elemente entfernen. In diesem Fall erhalten Sie
resultstatsDF_iris_methodnr-2_percentage-0.05_seed-0.wcr
Wie mache ich das in Bash?
Antwort1
Wenn du es wirklich tun willst"mit Bash", Dann
find . -name '*.wcr' -execdir bash -c '
shopt -s extglob; for f; do echo mv -- "$f" "${f/_+([0-9-])_/_}"; done
' bash {} +
Dies beruht auf einem erweiterten Glob +([0-9-])
, der einem oder mehreren Vorkommen von Zeichen im Satz entspricht[0-9-]
Sie könnten den Ersatz spezifischer gestalten, ${f/_2017+([0-9-])_/_}
wenn beispielsweise das bloße Abgleichen von Ziffern und Bindestrichen zu allgemein ist.
Hinweis: Entfernen Sie die echo
sobald Sie sicher sind, dass es das tut, was Sie wollen.
Antwort2
Verwenden Sie find
+prename
(Perl-Umbenennungs-)Befehle:
find yourfolder -type f -name "*.wcr" -exec prename 's/^(.+)_[0-9]{4}-[0-9]{2}-[0-9]{2}[^_]+(_.*)$/$1$2/' {} +
prename
Um das Ergebnis ohne Aktion anzuzeigen, fügen Sie -n
die Option (Namen der umzubenennenden Dateien drucken, aber nicht umbenennen):
man rename
[0-9]{4}-[0-9]{2}-[0-9]{2}
- Muster zeigt aufDatum-ähnliche Teilzeichenfolge (zB2017-05-26
)
Antwort3
Verwendung derPerl umbenennenBefehl (beide Varianten, aber nicht util-linux rename
):
find . -type f -name \*.wcr -exec rename 's/_\d{4}-(\d{2}-){2}-(\d{2}-){3}\d+_/_/' {} +
Antwort4
Wenn die Dateien immer eine Verzeichnisebene tief liegen, können Sie sie mit etwas wie durchlaufen for x in */*_20*_*
. Welches Muster Sie verwenden, hängt davon ab, welche anderen Dateien vorhanden sein könnten, die Sie nicht umbenennen möchten. Das Muster, das ich gerade angegeben habe, geht davon aus, dass das Datum mit beginnt 20
und dass alle Dateien, deren Name _20
und danach ein weiterer Unterstrich enthalten, umbenannt werden sollten.
Sie können die Umbenennung mit einer Shell-Schleife durchführen, indem SieParametererweiterungKonstrukte zum Erstellen des neuen Dateinamens.
for old_name in ./*/*_20_*_*; do
base=${old_name##*/} # remove the directory part
prefix=${base%%_20*} # remove everything from _20
suffix=${base#*_20} # remove everything up to _20
suffix=${suffix#*_} # ... then everything before the first remaining _
mv "$old_name" "${old_name%/*}/${prefix}_${suffix}"
done
Wenn die Dateien in unterschiedlichen Tiefen liegen, können Sie in Bash ≥4.3 shopt -s globstar
then ausführen for x in **/*_20*_*; …
. DieMuster**
passt zu jeder Verzeichnistiefe, wenn globstar
eingeschaltet. Dies funktioniert auch in Bash 4.0–4.2 mit der Einschränkung, dass es auch symbolische Links zu Verzeichnissen durchläuft. Dies funktioniert auch in Zsh und Ksh, ohne Einschränkung, sofort in Zsh und mit set -o globstar
in Ksh.