bash-Script zur Umnummerierung beliebig großer Bildfolgen

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
Benutzeravatar
Yadgar
Beiträge: 983
Registriert: 22.11.2010 22:11:08
Wohnort: Qal'a-ye Nil, Bergisch-Afghanistan (linksrheinische Exklave)
Kontaktdaten:

bash-Script zur Umnummerierung beliebig großer Bildfolgen

Beitrag von Yadgar » 02.08.2016 15:36:11

Hi(gh)!

Da ich ich mich bei meinen Videoschnitt-Orgien mit ffmpeg schon seit längerem darüber ärgere, dass in Dolphin pro Funktionsaufruf immer nur maximal 10000 Dateien umbenannt werden können, habe ich mir kurzerhand ein Script geschrieben, das beliebig viele Dateien neue Framenummern zuweist:

Code: Alles auswählen

# bnr
# Batch rename tool
# `

#function digits()
digits()
{
  c=1
  d=0
  while [ $c -le $1 ]
  do
    c=$((c*10))
    d=$((d+1))
  done
  return $d
}

#function leadingzeroes()
leadingzeroes()
{
  lz=""
  for i in $(seq 0 $1)
  do
    lz=${lz}0
  done
  echo $lz
  return $lz
}  
 
echo "Niedrigste Quell-Framenummer:"
read minsframe
echo "Höchste Quell-Framenummer:"
read maxsframe
echo "Höchste Framenummern-Stellenzahl in der Gesamtserie:"
read maxdigits
echo "Neue Frame-Startnummer:"
read newstartframe

frames=$((maxframe-minsframe))
diff=$((newstartframe-minsframe))

series="worringen"
source="/media/yadgar/video/worringen4"
temp1="/media/yadgar/video/worringen4/worringen4-temp1"
temp2="/media/yadgar/video/worringen4/worringen4-temp2"

cd $source
mkdir $temp1
mkdir $temp2

for j in $(seq $minsframe $maxsframe)
do
  digits $j
  jdigits=$?
  leadingzeroes $((maxdigits-jdigits-1))
  zeroes=`leadingzeroes $((maxdigits-jdigits-1))`
  file=${series}-${zeroes}${j}.png
  cp $file $temp1
  echo "Frame $file wird kopiert"
  cd $temp1
  k=$((j+diff))
  digits $k
  kdigits=$?
  leadingzeroes $((maxdigits-kdigits-1))
  zeroes=`leadingzeroes $((maxdigits-kdigits-1))`
  newfile=${series}-${zeroes}${k}.png
  mv $file $newfile
  mv $newfile $temp2
  echo "und in $newfile umbenannt"
  cd $source
done

for j in $(seq $minsframe $maxsframe)
do
  digits $j
  jdigits=$?
  leadingzeroes $((maxdigits-jdigits-1))
  zeroes=`leadingzeroes $((maxdigits-jdigits-1))`
  file=${series}-${zeroes}${j}.png
  rm $file
  echo "Alter Frame $file wird gelöscht"
done

cd $temp2

for j in $(seq $newstartframe $((maxsframe+diff)))
do
  digits $j
  jdigits=$?
  leadingzeroes $((maxdigits-jdigits-1))
  zeroes=`leadingzeroes $((maxdigits-jdigits-1))`
  file=${series}-${zeroes}${j}.png
  mv $file ..
  echo "Frame $file wird verschoben"
done

rmdir $temp1
rmdir $temp2
Was könnte man daran noch verbessern? Mir fällt als erstes ein, in den Lösch- und Verschiebeschleifen abhängig von der Zahl der zu bearbeitenden Dateien reguläre Ausdrücke zu verwenden - also etwa rm serienname-0[0-4]* ,wohl wissend, dass ab irgendwas zwischen 50000 und 100000 Dateien die Fehlermeldung "Argumentliste zu lang" ausgegeben wird - deswegen hatte ich ja bislang Einzelaufrufe verwendet, die sind aber bei mehreren hunderttausend Einzelbildern doch etwas zeitraubend...

Was fällt Euch noch ein?

Bis bald im Khyberspace!

Yadgar

Now playing: Turn of the Century, live 1996 San Luis Obispo (Yes)
Bis bald im Khyberspace!

Yadgar

If operating systems were countries, Linux would be pre-1978 Afghanistan: an all-time favourite among alternative globetrotters, but shunned by mainstream tourists because of its lack of fancy beaches, shortage of alcoholic beverages and its fondness of beards...

Benutzeravatar
Meillo
Moderator
Beiträge: 9232
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: bash-Script zur Umnummerierung beliebig großer Bildfolge

Beitrag von Meillo » 03.08.2016 09:35:54

Es wuerde den Code und die Bedienung vereinfachen, wenn du sowas verwenden wuerdest:

Code: Alles auswählen

maxdigits=`printf "%s" "$maxsframe" | wc -c`
printf "%0${maxdigits}d" "$framenum"
Wenn du keine Anfangs- und Endframenummern brauchst, sondern auf allen arbeiten kannst, dann kannst du $maxsframes durch ``ls | wc -l'' ersetzen.

For-Schleifen scheitern irgendwann an zuvielen Argumenten; bei ``|while read'' passiert dies nicht.

Warum zwei identische Schleifen? Mach doch beides in einer.

Ich verstehe noch nicht, warum du Temp-Verzeichnisse brauchst. Wegen Kollisionen zwischen den Namen davor und danach? Dann solltest du vielleicht http://www.i0i0.de/toolchest/emv anschauen (weil das dieses Problem behandeln kann), das koenntest du mittels VISUAL=ed scripten ...

Insgesamt kommt mir dein Script deutlich zu komplex vor (darum ist auch wenig Motivation da, es detailliert durchdenken zu wollen).

Interaktive Scripte nehmen den Benutzer gefangen und sind schlecht automatisierbar. Verwende lieber Kommandozeilenargumente fuer die Werte, die du uebergeben musst, statt sie interaktiv abzufragen.
Use ed once in a while!

Benutzeravatar
hikaru
Moderator
Beiträge: 13901
Registriert: 09.04.2008 12:48:59

Re: bash-Script zur Umnummerierung beliebig großer Bildfolge

Beitrag von hikaru » 03.08.2016 10:34:53

Meillo hat geschrieben:Insgesamt kommt mir dein Script deutlich zu komplex vor (darum ist auch wenig Motivation da, es detailliert durchdenken zu wollen).
Geht mir ähnlich.
Gibt es einen Grund dafür, nicht einfach rename [1] zu nehmen?

[1] https://wiki.ubuntuusers.de/rename/

Benutzeravatar
Meillo
Moderator
Beiträge: 9232
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: bash-Script zur Umnummerierung beliebig großer Bildfolge

Beitrag von Meillo » 03.08.2016 12:15:49

hikaru hat geschrieben: Gibt es einen Grund dafür, nicht einfach rename [1] zu nehmen?

[1] https://wiki.ubuntuusers.de/rename/
Kann rename(1) Dateien aufsteigend nummerieren? Ich denke nicht.

Mein Vorschlag dafuer ist:

Code: Alles auswählen

#!/bin/sh
# Prefix ascending number to filenames
# Usage: number-files [ NUMDIGITS ] <filenamelist | sh

n=0
while read i ; do
        case "$i" in
        */*)    dir="${i%/*}/" ;;
        *)      dir="" ;;
        esac
        echo mv "$i" "$dir`printf %0${1:-4}d $n`-${i##*/}"
        n=`expr $n + 1`
done
Und dann:

Code: Alles auswählen

ls *.frame | number-files `ls | wc -l | wc -c` | sh
Daraus sollte sich doch etwas bauen lassen ...
Zuletzt geändert von Meillo am 03.08.2016 13:09:28, insgesamt 2-mal geändert.
Grund: Script verbessert, damit es mit absoluten Pfaden umgehen kann
Use ed once in a while!

Benutzeravatar
hikaru
Moderator
Beiträge: 13901
Registriert: 09.04.2008 12:48:59

Re: bash-Script zur Umnummerierung beliebig großer Bildfolge

Beitrag von hikaru » 03.08.2016 12:33:03

Meillo hat geschrieben:Kann rename(1) Dateien aufsteigend nummerieren?
Die Quelldateien sind doch schon nummeriert. In irgendeiner Form muss doch was auch immer sie erzeugt hat eine eindeutige Reihenfolge angelegt haben. Die Nummerierung muss nur noch in ein einheitliches Format gebracht werden, und der Serienname vorangestellt werden.

Benutzeravatar
Meillo
Moderator
Beiträge: 9232
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: bash-Script zur Umnummerierung beliebig großer Bildfolge

Beitrag von Meillo » 03.08.2016 12:43:04

hikaru hat geschrieben:
Meillo hat geschrieben:Kann rename(1) Dateien aufsteigend nummerieren?
Die Quelldateien sind doch schon nummeriert. In irgendeiner Form muss doch was auch immer sie erzeugt hat eine eindeutige Reihenfolge angelegt haben.
Diesen Teil des Script habe ich nicht zu verstehen versucht. (Wie so oft fehlet auch hier ein Input- und Output-Beispiel.)
Die Nummerierung muss nur noch in ein einheitliches Format gebracht werden,
Also muss doch (neu) nummeriert werden. ;-) Oder was soll ``in ein einheitliches Format bringen'' sonst bedeuten?
und der Serienname vorangestellt werden.
Das kann rename(1) natuerlich.



Ach, es ist doch eine elende Raterei, wenn man es weder selbst komplett durchdenkt (worauf ich keine Lust habe, denn ich hab schon genug anderen verwirrenden Code den ich verstehen muss!) oder entsprechenden Input vom Fragenden bekommt. Ich bin wieder mit dabei, wenn zweiteres der Fall ist.
Use ed once in a while!

Benutzeravatar
heisenberg
Beiträge: 4123
Registriert: 04.06.2015 01:17:27
Lizenz eigener Beiträge: MIT Lizenz

Re: bash-Script zur Umnummerierung beliebig großer Bildfolge

Beitrag von heisenberg » 03.08.2016 12:55:06

Ich habe den Thread auch nicht ganz gelesen. Nur zu diesem Kommentar:
Meillo hat geschrieben:Kann rename(1) Dateien aufsteigend nummerieren?
Ja. Kann es. Man kann perl-Code verwenden.

Code: Alles auswählen

rename  -E 'our $count //= 0; CORE::rename $_,$_.$count++;'  datei1 datei2 datei3 ...

Benutzeravatar
hikaru
Moderator
Beiträge: 13901
Registriert: 09.04.2008 12:48:59

Re: bash-Script zur Umnummerierung beliebig großer Bildfolge

Beitrag von hikaru » 03.08.2016 13:07:09

Meillo hat geschrieben:Also muss doch (neu) nummeriert werden. ;-) Oder was soll ``in ein einheitliches Format bringen'' sonst bedeuten?
So wie ich den Code beim Überfliegen verstanden habe, werden da nur führende Nullen aufgefüllt.
heisenberg hat geschrieben:Ja. Kann es. Man kann perl-Code verwenden.

Code: Alles auswählen

rename  -E 'our $count //= 0; CORE::rename $_,$_.$count++;'  datei1 datei2 datei3 ...
Das war mir neu! 8O
D.h., am Ende kann rename auch noch Kaffee kochen.

Benutzeravatar
Meillo
Moderator
Beiträge: 9232
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: bash-Script zur Umnummerierung beliebig großer Bildfolge

Beitrag von Meillo » 03.08.2016 13:13:43

hikaru hat geschrieben:
Meillo hat geschrieben:Also muss doch (neu) nummeriert werden. ;-) Oder was soll ``in ein einheitliches Format bringen'' sonst bedeuten?
So wie ich den Code beim Überfliegen verstanden habe, werden da nur führende Nullen aufgefüllt.
Das geht ja noch einfacher:

Code: Alles auswählen

file=123-foo
printf "%08d-%s\n" "${file%%-*}" "${file#*-}"

... Mist! Jetzt hab ich mich doch zur einer weiteren Antwort hinreissen lassen. :roll:
Use ed once in a while!

Benutzeravatar
Meillo
Moderator
Beiträge: 9232
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: bash-Script zur Umnummerierung beliebig großer Bildfolge

Beitrag von Meillo » 03.08.2016 13:16:21

hikaru hat geschrieben: 8O
D.h., am Ende kann rename auch noch Kaffee kochen.
http://www.perlmonks.org/?node_id=886566 :wink:
Use ed once in a while!

Antworten