Mehrere Dateien umbenennen, um die Nummer im Dateinamen zu verringern?

Mehrere Dateien umbenennen, um die Nummer im Dateinamen zu verringern?

Ich habe falsch benannte Dateien, die nicht mit -1 synchronisiert sind. Das Problem ist, dass ich Tausende davon umbenennen muss.

  • DBGC180_805754
  • DBGC180_805755
  • DBGC180_805756

Zu

  • DBGC180_805753
  • DBGC180_805754
  • DBGC180_805755

Ich würde lieber Bash-Skripte oder einen Unix-Befehl verwenden.

Antwort1

Du kannst das:

# {smallestfilenum..largestfilenum}

for i in {805754..999999}; do 
   mv "DBGC180_$i" "DBGC180_$(($i-1))";
done

Probieren Sie es mit einer kleinen Zahl (sagen wir 805754..805758), um sicherzustellen, dass es wie erwartet funktioniert. Beachten Sie, dass eine bereits vorhandene Datei mit dem neuen Namen überschrieben wird.

Antwort2

  1. Verschieben Sie die umzubenennenden Dateien in ein Unterverzeichnis (ohne ihren Namen zu ändern).
  2. Benennen Sie die Dateien aus dem Unterverzeichnis in das Originalverzeichnis um.

Es gibt zwei Gründe, warum ich Schritt 1 empfehle, auch wenn es auch ohne möglich ist:

  • Wird der Befehl unterbrochen, können Sie direkt dort fortfahren, wo Sie aufgehört haben, da sofort ersichtlich ist, welche Dateien bereits umbenannt wurden und welche nicht.
  • Sie müssen sich keine Sorgen machen, dass Sie die Umbenennung in der falschen Reihenfolge vornehmen und eine der vorhandenen Dateien überschreiben.

Ungetesteter Shell-Ausschnitt (basierend auf der Tatsache, dass die zu dekrementierende Zahl niemals führende Nullen hat):

mkdir to_decrement
for x in DBGC180_80575[4-9] DBGC180_8057[6-9]? DBGC180_805[8-9]?? DBGC180_80[6-9]??? DBGC180_8[1-9]???? DBGC180_9?????; do
  mv "$x" to_decrement/
done
cd to_decrement
for x in *; do
  number="${x##*_}"
  mv -i -- "$x" "../${x%_*}_$((number-1))"
done
cd ..
rmdir to_decrement

Mitzshkönnen Sie dies viel einfacher machen, dank seinernumerischer Bereich Glob, es isteingebautmvwodurch die Längenbeschränkungen für Befehlszeilen vermieden werden undMusterbasierte Massenumbenennungsfunktion. In zsh:

autoload -U zmv
zmodload -m -F zsh/files b:zf_\*
mkdir to_decrement
zf_mv DBGC180_<805754-> to_decrement/
zmv 'to_decrement/(*)_(*)' '${1}_$(($2-1))'
rmdir to_decrement

Antwort3

DBGC180_805754Sie möchten also in DBGC180_805753, ...55in ...54usw. umbenennen . Mit diesem Problem werde ich mich befassen.

Platzieren Sie dieses Skript zunächst irgendwo in Ihrem PATHund nennen Sie es waltinator.

#!/bin/bash
#step through the parameters 
while [[ -n "$1" ]] ; do
    oldname="$1"
    # shift the arguments left
    shift;
    # strip off the fixed part of the old name
    oldnum=${oldname##DBGC180_}
    # decrement the number (this is what was wanted, right?)
    newnum=$(( $oldnum - 1 ))
    # build the new, improved filename
    newname="DBGC180_$newnum"
    if [[ -f "$newname" ]] ; then
        printf "Cannot rename $oldname to $newname, $newname exists.\n" >&2
        exit 1
    fi
    mv --no-clobber "$oldname" "$newname"
done
exit 0

Gehen Sie für den nächsten Schritt davon aus, dass sich das Skript in befindet $HOME/bin/waltinatorund Sie Folgendes haben chmod +x $HOME/bin/waltinator:

find . -type f -name 'BDGC180_[0-9][0-9][0-9][0-9][0-9][0-9]` -print | \
    sort | \
    xargs $HOME/bin/waltinator

Das findfindet Dateien (in keiner bestimmten Reihenfolge), deren Namen dem Shell-Glob-Muster " BDGC180_gefolgt von 6 Ziffern ( [0-9]) entsprechen. Da wir eine sortierte Liste wollen (es wäre ein Fehler, vor dem Umbenennen ...97in umzubenennen ), führen wir die Ausgabe von über aus . Dann verwenden wir , um die (sortierte) Liste der Dateinamen zu übernehmen und erstellen einen Befehl, um die (sortierte) Liste der Dateinamen an zu übergeben . Lesen Sie , ob Sie die Argumentliste kürzen müssen....96...96findsortxargs$HOME/bin/waltinatorman xargs

Lesen Sie dazu:

for page in bash mv find sort xargs ; do
    man "$page"
done   

Antwort4

Verwenden Sie renamediese Option, um jede Zahl durch sich selbst minus 1 zu ersetzen.

$ rename -v 's/\d{6}/sprintf("%06",($&-1))/e'    

Anmerkungen

  • renameverwendet Perl-Ausdrücke zum Umbenennen von Dateinamen.
  • sgibt an, dass renameeinige oder alle Dateinamen ersetzt werden, die dem regulären Ausdrucksmuster entsprechen.
  • Perl-Substitutionsausdrücke sind wie folgt strukturiert.
    • s/PATTERN/REPLACEMENT/MODIFIER
  • \d{6}ist das Muster, nach dem renamegesucht und das ersetzt wird. Es besteht aus 6 Dezimalstellen.
  • $ist die Variable, die die übereinstimmende Teilzeichenfolge speichert \d{6}(in diesem Fall ist die „Teilzeichenfolge“ eine Ganzzahl).
  • sprintf("%06",($&-1))ruft den in gespeicherten Wert ab $, dekrementiert ihn und gibt dann diesen Wert als Ersatz zurück. Das %06ist da, um führende Nullen zu verarbeiten.
  • eangegeben, das renameden Ersetzungstext auswertet, als handele es sich um eine Perl-Anweisung, und seinen Rückgabewert als Ersetzungstext verwendet.
  • -vmacht renameecho, was es tut.

Wenn Sie besonders sicher sein wollen, verwenden Sie die Flagge -n, sodass renameSie nur erfahren, was getan werden soll, anstatt es auszuführen.

Dies scheint nur beim Dekrementieren zu funktionieren, gehen Sie also vorsichtig damit um.

verwandte Informationen