Batch-Umbenennung von Bilddateien nach Alter sowie Hinzufügen von Datum und Variable zum Dateinamen

7

Die Frage wurde aufgrund der Erkenntnisse aus den ersten beiden Antworten und Kommentaren, die mir beim ersten Fragen nicht bekannt waren, komplett neu geschrieben.


Nach einem Fotoshooting komme ich mit Dateien nach Hause, die aussehen _DSC1234.NEF. NEFist das Rohdateiformat für die Kamera von Nikon, sodass EXIFDaten in den Dateien vorhanden sind.

Ich möchte sie automatisch in drei Teile umbenennen:

  1. Erstellungsdatum im Format YYYYMMDD
  2. Name des Schusses
  3. Anzahl der Bilder

Der endgültige Dateiname sollte also so aussehen

20140707_NameOfShoot_0001.NEF

Es gibt einige Probleme:

Anzeige 1. Erstellungsdatum Manchmal kann ich die Dateien nur einige Tage nach der Aufnahme kopieren und umbenennen. Das Datum sollte also das Aufnahmedatum und nicht das Kopierdatum widerspiegeln. mtimescheint hier die beste Wahl zu sein oder wenn möglich Erstellungsdatum von EXIF.

Anzeige 2: Name des Shoots Dies wäre idealerweise eine Variable, die ich beim Aufrufen des Skripts als Parameter festlegen könnte.

ad 3. Anzahl der Bilder Dies sollte das Alter des Bildes widerspiegeln, wobei das älteste die niedrigste Anzahl hat. Das Problem ist, dass Kameras die Nummerierung normalerweise 0000nach dem Treffer neu starten 9999. So 9995-9999kann möglicherweise älter als 0000-0004. Ich suche nach einer Lösung, die das Alter der Datei widerspiegelt und in diesem speziellen Fall umbenennen würde

  • _DSC0000.NEF -> 20140707_FOO_0004.NEF
  • _DSC0001.NEF -> 20140707_FOO_0005.NEF
  • _DSC0002.NEF -> 20140707_FOO_0006.NEF
  • ...
  • _DSC9997.NEF -> 20140707_FOO_0001.NEF
  • _DSC9998.NEF -> 20140707_FOO_0002.NEF
  • _DSC9999.NEF -> 20140707_FOO_0003.NEF

Auch hier scheint entweder mtimeoder wenn möglich das Erstellungsdatum von EXIFrichtig zu sein.


Von hier aus habe ich eine funktionierende Lösung, die alle .NEF-Dateien in einem Ordner nach Datum umbenennt:

find -name '*.NEF' | 
gawk 'BEGIN{ a=1 }{ printf "mv %s %04d.NEF\n", $0, a++ }' | 
bash 

Das Änderungsdatum der Hardcodedatei und der Shootname funktionieren gut, aber es wäre großartig, wenn es automatisiert werden könnte.

Für die Zeitmarke I Artikel finden auf strftime(), mktime(), systime()aber ich verstehe nicht, wie sie verwenden , um Dateiänderungsdatum zurück. Ich habe auch versucht, die Gawk-Zeile hinzuzufügen DATE=$(date +"%Y%m%d")und zu ergänzen $DATE, was zum Löschen aller Dateien im aktuellen Ordner führt (und wahrscheinlich sowieso Systime ist und die Zeit nicht ändert).

Für die Variable habe ich versucht

gawk 'BEGIN{ a=1 }{ printf "mv %s $1_%04d.NEF\n", $0, a++ }' | 

und rufen Sie das Skript mit auf ./rename FOO, aber FOO wird beim Umbenennen ignoriert.

Seul
quelle
Ich habe auch versucht, digikam für das Batch-Umbenennen zu verwenden, was gut funktioniert, aber bei meinen letzten über 1600 Fotos ungefähr 1 Sekunde / Datei benötigt hat, was ich etwas langsam finde
Seul
Ich habe es gerade stat -c %W -- *in meinem Home-Verzeichnis versucht und nur ein paar Nullen zurückgegeben. Auf der man findSeite von GNU wird auch dokumentiert, dass -printf strftimeSequenzen für %AZugriff, Statusänderung %Cund Änderung %Tverarbeitet werden können, jedoch nichts über die Erstellung oder Geburt von Dateien. Das beweist zwar nicht unbedingt, dass dies nicht möglich ist, aber ich denke, es ist ein guter Indikator dafür, dass es sich nicht um eine allgemein verfügbare Funktion handelt.
Mikeserv
Hm. Was ist der Unterschied zwischen Änderung und Modifikation? Das würde wahrscheinlich sowieso reichen. Wenn die Geburt nicht verfügbar ist, können Sie sehen, was die obige Lösung zum Sortieren verwendet? Weil ich nicht wirklich verstehe, was es tut.
Seul
Das ist Statusänderung. Schauen Sie hier - ich denke, es ist auch ein ziemlich guter Indikator. Vielleicht gibt es Dateisysteme, die über die Erstellungszeit berichten - ich bin mir nicht sicher -, aber ich glaube nicht, dass viele dies tun.
Mikeserv
großartig, vielen Dank. und ja, das sollte reichen. Hast du eine Idee, wie ich das in meinen Dateinamen einfügen kann?
Seul

Antworten:

8

Die meisten Unices verfolgen das Erstellungsdatum einer Datei nicht¹. "Erstellungsdatum" ist ohnehin schlecht definiert (erstellt das Kopieren einer Datei eine neue Datei?). Sie können die Änderungszeit der Datei verwenden, die nach vernünftiger Interpretation das Datum ist, an dem die neueste Version der Daten erstellt wurde. Wenn Sie Kopien der Datei erstellen, achten Sie darauf, die Änderungszeit beizubehalten (z. B. cp -poder cp -awenn Sie den cpBefehl verwenden, nicht nackt cp).

Einige Dateiformate enthalten ein Feld in der Datei, in das die Erstelleranwendung ein Erstellungsdatum eingibt. Dies ist häufig bei Fotos der Fall, bei denen die Kamera einige Exif- Daten in JPEG- oder TIFF-Bildern ausfüllt , einschließlich der Erstellungszeit. Das NEF-Bildformat von Nikon umschließt TIFF und unterstützt auch Exif.

Es gibt vorgefertigte Tools zum Umbenennen von Bilddateien mit Exif-Daten, um das Erstellungsdatum in den Dateinamen aufzunehmen. Das Umbenennen von Bildern, um das Erstellungsdatum in den Namen aufzunehmen, zeigt zwei Lösungen: exiftool und exiv2 .

Ich glaube nicht, dass Sie mit einem der beiden Tools einen Zähler in den Dateinamen aufnehmen können. Sie können Ihre Umbenennung in zwei Durchgängen vornehmen: Fügen Sie zuerst das Datum (mit einer möglichst hohen Auflösung, um die Reihenfolge beizubehalten) in den Dateinamen ein, nummerieren Sie dann die Dateien entsprechend diesem Datumsteil (und geben Sie die Uhrzeit ein). Da moderne DSLRs Bildbursts auslösen können (Nikons D4s schießt mit 11 Bildern pro Sekunde), ist es ratsam, auch in der ersten Phase den ursprünglichen Dateinamen beizubehalten, da dies sonst möglicherweise zu mehreren Dateien mit demselben Dateinamen führen würde.

exiv2 mv -r %Y%m%d-%H%M%S:basename: *.NEF
# exiv2 uses `strftime(3)`, so `%Y%m%d-%H%M%S` returns YYYYMMDD-hhmmss
# :basename: is a naming variable exiv2's `-r`-handle provides. See `exiv2 -h` for more  
# Now you have files with names like 20140630-235958_DSCC1234.NEF.
# Note that chronological order and lexicographic order agree with this naming format.
i=10000
for x in *.NEF; do
  i=$((i+1))
  mv "$x" "${x%-*}_FOO_${i#1}.NEF"
done

${x%-*}Entfernt den Teil nach dem -Zeichen. Die Zählervariable izählt ab 10000 und wird verwendet, wobei die führende 1Ziffer entfernt wird. Dies ist ein Trick, um die führenden Nullen zu erhalten, sodass alle Zählerwerte dieselbe Zahl haben.

Das Umbenennen von Dateien durch Inkrementieren einer Zahl innerhalb des Dateinamens bietet andere Lösungen zum Umbenennen einer Reihe von Dateien, um einen Zähler einzuschließen.

Wenn Sie den Zeitstempel einer Datei anstelle von Exif-Daten verwenden möchten, lesen Sie Umbenennen einer Reihe von Dateien mit dem Datumsänderungsstempel am Ende des Dateinamens.


Generieren Sie im Allgemeinen keinen Shell-Code und leiten Sie ihn dann in eine Shell weiter. Es ist unnötig verwickelt. Zum Beispiel anstelle von

find -name '*.NEF' | 
gawk 'BEGIN{ a=1 }{ printf "mv %s %04d.NEF\n", $0, a++ }' | 
bash

Du kannst schreiben

find -name '*.NEF' | 
gawk 'BEGIN{ a=1 }{ system(sprintf("mv %s %04d.NEF\n", $0, a++)) }'

Beachten Sie, dass beide Versionen zu katastrophalen Ergebnissen führen kann , wenn ein Dateiname Shell Sonderzeichen (wie Leerzeichen enthalten ', $, `, etc.) , da der Dateiname wird als Shell - Code interpretiert. Es gibt Möglichkeiten, dies in robusten Code umzuwandeln, aber dies ist nicht der einfachste Ansatz, daher werde ich diesen Ansatz nicht weiterverfolgen.


¹ Beachten Sie, dass es etwas gibt, das als "ctime" bezeichnet wird, aber cnicht zur Erstellung , sondern zur Änderung . Die ctime ändert sich jedes Mal, wenn sich etwas an der Datei ändert, entweder in ihrem Inhalt oder in ihren Metadaten (Name, Berechtigungen, ...). Die ctime ist so ziemlich das Gegenteil einer Schöpfungszeit.

Gilles 'SO - hör auf böse zu sein'
quelle
Sie machen einen sehr allgemeinen Punkt und stützen ihn dann auf sehr spezifische Beispiele - dies kommt einem unbegründeten Argument sehr nahe . Generieren Sie keinen Shell-Code und leiten Sie ihn dann an eine Shell weiter. Dies ist die Anweisung, auf die ich mich beziehe. Hier gibt es eine andere Antwort, die dies bereits robust macht, aber die Methode, für die Sie scheinbar völlig ignoriert haben.
Mikesserv
Danke für deinen Beitrag. Es funktioniert ziemlich gut, hat aber zwei kleine und ein größeres Problem.
Seul
@Seul Wie sehen die ursprünglichen Dateinamen aus? Ich dachte, NameOfShootdas wäre vom ursprünglichen Dateinamen. In Bezug auf die Daten bin ich mit dem NEF-Format nicht vertraut. Enthält es einen Erstellungsstempel im Dateiformat? Beispielsweise können JPEG-Bilder das Datum enthalten, an dem das Bild aufgenommen wurde (es ist Teil der EXIF-Daten). Viele (aber nicht alle) Kameras tun dies. Möchten Sie in Bezug auf die Sortierung, dass die älteste Datei 0001, die nächstälteste 0002 usw. ist?
Gilles 'SO - hör auf böse zu sein'
Ja, NEF ist Nikons Kamera-Raw-Format, also sind alle exif si vorhanden. Das Originalformat ist _DSC1234.NEF, wird das auch zur Originalfrage hinzufügen.
Seul
und ja, der älteste sollte die niedrigste Zahl bekommen. –– Nebenbemerkung: Ich werde von stackexchange gefragt, ob ich lieber chatten möchte, als all dies zu Kommentaren hinzuzufügen. Ich bin mit der Etikette hier nicht allzu vertraut. Bitte lassen Sie mich wissen, ob ich meinen Stil verbessern kann.
Seul
4
stat --printf='}" "%z_${SN}_${LINENO}"\n' -- * | 
nl -nln -w1 -s '' |
sort -k2,3 | 
sed 's| ..:[^_]*||;s|-||g;s|^|echo mv "${|' |
SN=SHOOTNAME sh -s -- *

Der obige Befehl sollte das tun, was Sie brauchen. Es ist vielleicht allgemeiner als Sie es gewünscht haben - aber bitte sehen Sie am Ende dieser Antwort ein spezifischeres Beispiel.

Es funktioniert, indem *alle Dateien im aktuellen Verzeichnis globalisiert und ihre Änderungszeiten ausgedruckt werden. Für nur Dateien im aktuellen Verzeichnis, die das Suffix enthalten .NEF, möchten Sie den *Globstar an den Enden der Zeilen 1 und 5 in ändern *.NEF. Es werden einige Shell-Variablen und Anführungszeichen an das Ende angehängt - deren Namen nur am anderen Ende der Pipeline in der shSubshell vorhanden sind.

Da wir die Dateinamen nur anhand ihrer Glob-Reihenfolge oder der ${1}Shell-Typparameter angeben, funktioniert dies auch mit jedem Dateinamen - unabhängig davon, welche seltsamen Zeichen darin enthalten sind.

Im echoMoment enthält der Befehl ein - es ist nerfed. Laufen ist im Wesentlichen ein No-Op - es zeigt Ihnen nur, was es tun möchte. Hier ist die Ausgabe aus meinem Home-Verzeichnis, bevor es an Folgendes weitergeleitet wird sh:

echo mv "${2}" "20140611_${SN}_${LINENO}"
echo mv "${4}" "20140614_${SN}_${LINENO}"
echo mv "${11}" "20140617_${SN}_${LINENO}"
echo mv "${7}" "20140622_${SN}_${LINENO}"
echo mv "${8}" "20140622_${SN}_${LINENO}"
echo mv "${1}" "20140624_${SN}_${LINENO}"
echo mv "${10}" "20140704_${SN}_${LINENO}"
echo mv "${5}" "20140704_${SN}_${LINENO}"
echo mv "${9}" "20140704_${SN}_${LINENO}"
echo mv "${12}" "20140705_${SN}_${LINENO}"
echo mv "${3}" "20140705_${SN}_${LINENO}"
echo mv "${13}" "20140706_${SN}_${LINENO}"
echo mv "${6}" "20140706_${SN}_${LINENO}"

Hier ist es nach sh:

mv Desktop-1 20140611_SHOOTNAME_1
mv Library 20140614_SHOOTNAME_2
mv target.txt 20140617_SHOOTNAME_3
mv script.sh 20140622_SHOOTNAME_4
mv script.sh~ 20140622_SHOOTNAME_5
mv Desktop 20140624_SHOOTNAME_6
mv shot-2014-06-22_17-11-06.jpg 20140704_SHOOTNAME_7
mv Terminology.log 20140704_SHOOTNAME_8
mv shot-2014-06-22_17-10-16.jpg 20140704_SHOOTNAME_9
mv test 20140705_SHOOTNAME_10
mv Downloads 20140705_SHOOTNAME_11
mv test.tar 20140706_SHOOTNAME_12
mv new
file 20140706_SHOOTNAME_13

Möglicherweise stellen Sie fest, dass in meiner Ausgabe einige Bilddateien angezeigt werden, die bereits nach ihrer Erstellungszeit benannt wurden, deren neu zugewiesener Name jedoch nicht übereinstimmt. Dies ist keine Auswirkung von sort- was wie vorgeschrieben funktioniert -, sondern dass diese Dateien zuletzt an diesem Datum eine Statusänderung hatten. Wie Sie in den Kommentaren zu dieser Frage angegeben haben, ctimehandelt es sich jedoch um die Eigenschaft, nach der Sie suchen. Dies ist die hier angebotene Eigenschaft für Sortierung und Name. Hier ist jedoch statdie Ausgabe mit angehängten Dateinamen:

stat -c '%z %n' -- *

2014-06-24 16:50:09.110283839 -0700 Desktop
2014-06-11 23:34:02.981981145 -0700 Desktop-1
2014-07-05 01:00:43.213344635 -0700 Downloads
2014-06-14 10:32:13.537014418 -0700 Library
2014-07-04 23:02:25.079690701 -0700 Terminology.log
2014-07-06 11:24:05.398936386 -0700 new
file
2014-06-22 11:26:53.658004123 -0700 script.sh
2014-06-22 11:26:53.658004123 -0700 script.sh~
2014-07-04 13:34:00.063296353 -0700 shot-2014-06-22_17-10-16.jpg
2014-07-04 13:34:00.066629687 -0700 shot-2014-06-22_17-11-06.jpg
2014-06-17 19:59:38.475358571 -0700 target.txt
2014-07-05 23:53:39.097065292 -0700 test
2014-07-06 00:38:57.060521397 -0700 test.tar

Die obige Ausgabe soll mir auch helfen, zu demonstrieren, was die gesamte Pipeline tut.

  • So stat --printf='}" "%z_${SN}_${LINENO}"\n'druckt Linien , die wie folgt aussehen:

    }" "YYYY-MM-DD HH:MM:SS.NS -TZ_${SN}_${LINENO}"

... wo YMDHMS.NS -TZsind die verschiedenen strftimeKomponenten , die sie repräsentieren für ctime. Das Ausgabeformat ist identisch für %w- Zeitpunkt der Geburt der Datei - %x- Zeitpunkt des letzten Zugriffs - oder %y- Zeitpunkt der letzten Änderung. Wenn Sie also eines dieser Elemente %zin der obigen Anweisung ersetzen, wird es stattdessen auf ihre Werte erweitert. Wie wir bereits in den Kommentaren besprochen haben, ist die %wGeburtszeit der Datei kein verlässliches Attribut, und wenn sie nicht unterstützt wird, wird sie nur auf erweitert 0.

Dies geschieht für jede Datei, in der sich die Shell-Globs befinden, *oder für die von Ihnen bereitgestellten Shell-Globs - beispielsweise *.NEFnur für Dateien im aktuellen Verzeichnis mit dem .NEFSuffix.

  • Diese Liste wird übergeben, an nlwelche Zahlen jede Zeile um 1 erhöht wird. Ihre -nZeilennummern sind linksbündig lnund nicht mit einer Mindest- -wID von 1 und nur einer ''Nullzeichenfolge -saufgefüllt, um sie vom Inhalt der Zeile zu trennen. Es gibt aus:

    I}" "YYYY-MM-DD HH:MM:SS.NS -TZ_${SN}_${LINENO}"

... wo Iist die Nummer jeder Zeile.

  • sortsortiert seine Eingabe vom -k2,3zweiten Feld bis zum dritten - oder weiter YYYY-MM-DD HH:MM:SS.NS. Da zu diesem Zeitpunkt die einzige eindeutige Qualität einer Zeile entweder Idas Datum oder das Datum ist und Iübersprungen wird, müssen keine genaueren Angaben gemacht werden. Dies betrifft auch den Kommentar, den Sie zu Dateien abgegeben haben, die nach Nummer und nicht nach Datum benannt sind. Ich sollte das getan haben , sortbevor sedin erster Linie , aber es fiel mir nicht auf Minuten zu sortieren und Sekunden und dergleichen.

Meine Testbasis dafür wurde wie folgt generiert:

for s in 9 8 7 6 5 4 3 2 1; do touch $s && sleep 1; done

Wenn ich sort nach sed - wie ich vor diesem bearbeiten tue - dann würde diese Dateien umbenennen , so dass 9ich ${DATE}.SHOOTNAME.9da jede Datei YMDFelder sind identisch und sortwürden nicht ihre Linie Ordnung beeinflussen. Bei dieser Einstellung ist dieser Befehl jedoch sortspezifisch für die Nanosekunde und wird daher 9in ${DATE}.SHOOTNAME.1und umgekehrt für umbenannt 1. Danke, @Seul, dass du mich darauf aufmerksam gemacht hast.

  • sedEntfernt dann die erste Zeichenfolge, die aussieht, <space><any char><any char>:<colon>und alle nachfolgenden Zeichen, die ^kein _Unterstrich sind. An diesem Punkt sieht die Linie also so aus:

    I}" "YYYY-MM-DD_${SN}_${LINENO}"

... als nächstes werden alle -Striche entfernt. Und schließlich wird es echo mv "${am ^Kopf jeder Zeile eingefügt, also sieht es so aus:

echo mv "${I}" "YYYYMMDD_${SN}_${LINENO}"
  • Zuletzt wird eine shEll mit der $SNdeklarierten Umgebungsvariablen aufgerufen - hier ist ihr Wert SHOOTNAME. POSIX gibt an, dass die Shell die Variable $LINENOfür jede Zeile, die sie einliest, erhöht. Daher sollte der Wert im Dateinamen für jede Zeile, die wir eingeben, auf eins mehr als die letzte erweitert werden. Wenn dies - wie aus Ihren Kommentaren hervorgeht - aus irgendeinem Grund nicht auftritt, wird ein vollständig gültiger Ersatz $((i=i+1))wie zuerst statin Zeile 1 der Pipeline gedruckt und wie ich in einem speziellen Beispiel unten angegeben habe.

Die Shell wird auch mit ihren Positionsparametern aufgerufen, die auf unseren Glob eingestellt sind - hier der *Globstar für alle Dateien im aktuellen Verzeichnis. Wie bereits erwähnt, würde *.NEFin dieser und in der ersten Zeile nur Dateien im aktuellen Verzeichnis mit dem Dateinamensuffix von bearbeitet .NEF.

Solange der Globus mit dem in der ersten Zeile identisch ist, werden sie in der Reihenfolge sortiert, in der sie nlnummeriert sind. Unabhängig davon, in welcher Zeile es auftritt, "${1}"wird es auf denselben Dateinamen erweitert, den wir ihm entsprechend der nlAusgabe zugewiesen haben . Auf diese Weise können Sie die Dateien in Datumsreihenfolge schnell und sicher und in der richtigen Reihenfolge umbenennen.

  • Wie auch schon erwähnt, habe ich den Befehl echohier mit nerfed . Aber wenn Sie das ausführen echound feststellen, dass es zu Ihnen passt, müssen Sie das entfernen echo.

So was:

stat --printf='}" "%z_${SN}_${LINENO}"\n' -- * | 
nl -nln -w1 -s '' |
sort -k2,3 |
sed 's| ..:[^_]*||;s|-||g;s|^|mv "${|' |
SN=SHOOTNAME sh -s -- *

Oder vielleicht:

export SN=SHOOTNAME SUFX=.NEF
stat --printf='}" "%z_${SN}_$((i=i+1))${SUFX}"\n' -- *$SUFX | 
nl -nln -w1 -s '' |
sort -k2,3 |
sed 's| ..:[^_]*||;s|-||g;s|^|mv "${|' |
sh -s -- *$SUFX

Und hier wird es in eine Shell-Funktion eingearbeitet:

_batch_date_rename () ( # a big one
    ERR= # for error reporting
    export "DIR=$1" "SUFX=$2" \ # args 1,2 must be dirname and file suffix
        "NAME=${3-${ERR:?no rename string specified}}" \ # need name string
        "TIME=${4-%y}" INT=$((${INT:-25}*3)) ${NOCONFIRM+NOCONFIRM=}
        #all above vars are exported to all points below
    _path_chk () { #run once at start - fn quits if any below test fails
        [ -d "$1" ] && [ -w "$1" ] && set -- "$1"/*"$2" && [ -e "$1" ]
    } # chks for user writable dirname and resolvable $1/*$2 glob
    _print_fmt () { #shell printf now not stat - last field zero padded
        printf 'mv "${%d}" "${DIR}/%d_${NAME}_%04d${SUFX}"\n' "$@"
    }
    _print_mv () { #prints copy of mv action before attempting 
        echo '(set -x' #uses shells debug printer to show expanded vals
        printf ': ${0+%s}\n' "$@" \
            ${NOCONFIRM-'Key "ENTER" to accept or "CTRL+C" to quit'}
        echo \) #above can be disabled by declaring NOCONFIRM at invocation
    } #by default fn batches 25 mvs at a time, displays them, and confirms
    _read_loop () { #parses piped in with IFS, batches in INTerval of 25
        argc=${1-$argc} ; ${1+shift} #total globbed files - quit point
        while IFS=' -' read nl y m d na ; do #split on -
            set -- "$@" "$nl" "$y$m$d" "$((i=i+1))" #build array until
            [ "$#" -ge "$INT" ] && break #hit interval
        done ; IFS='
';      set -- $(_print_fmt "$@") && unset IFS #finalize array in _print_fmt
        _print_mv "$@" #do the debug out
        ${NOCONFIRM+:} read < /dev/tty #if $NOCONFIRM not set confirm
        printf '%s\n' "$@" #now print the actual command
        [ $((argc>i)) -eq 1 ] || echo 'exit 0' #check if quit point     
        _read_loop #if not quit repeat
    }                                                                    
    _pipeline () { #this is mostly same - no sed though
        stat -c "$TIME" -- "$@" | nl -nln -w1 -s ' ' | sort -k2,3 | {
            _read_loop $# || echo 'exit 1' #read loop stands in for sed
        } | sh -s -- "$@" #sh still evaluates on args
    } #only two calls from main function below
    _path_chk "$1" "$2" || ${ERR:?Invalid pathname parameters specified}
    _pipeline "$DIR"/*"$SUFX" #if _path_chk do _pipeline
) #that's all folks

Das nutzt die Shell für einige Dinge, die ich mit anderen Dienstprogrammen gemacht habe. Das Konzept ist das gleiche - eine Dateiliste erstellen, auf verschiedene Arten sortieren und die Sortierreihenfolge speichern. Was an diesem Gedanken wirklich anders ist, ist, dass er Verschiebungsvorgänge stapelweise nach Intervallen stapelt, dem Benutzer anzeigt, was zu tun ist, und auf eine Eingabeaufforderung wartet, bevor er fortfährt. Ich habe mich hier damit aufgezeichnet, damit Sie eine Terminalsitzung sehen können, wie es funktioniert.

mikeserv
quelle
2
Zunächst einmal vielen Dank, dass Sie sich die Zeit genommen haben, sich das auszudenken und es so gut zu erklären. Ich weiß das wirklich zu schätzen. Es geht jedoch so weit über mein Können hinaus, dass ich selbst mit Ihren tiefgreifenden Erklärungen nicht viel verstehe. Wenn ich das Skript in einem Verzeichnis von Testdateien ausführe (das Skript befindet sich im selben Verzeichnis), wird angezeigt, dass alle Dateien in denselben Dateinamen umbenannt werden. Es werden keine inkrementierten Zahlen angezeigt. Wenn ich die Version ohne Echo ausführe, sind alle Dateien danach verschwunden und das Skript selbst wird umbenannt in20140707_SHOOTNAME_
Seul
@Seul? Warum hast du es ohne Echo ausgeführt? Oh, ich verstehe, mit Testdateien - sorry. Es zeigt, dass, weil aus irgendeinem Grund Ihr sh nicht unterstützt $LINENO. Kannst du es versuchen echo $LINENO? Ich verstehe nicht, warum es nicht unterstützt wird - Sie haben die Anführungszeichen genau kopiert, oder? Sie sind wichtig. Und ich kann nicht dafür sprechen bash- daher würde ich es nicht empfehlen -, shsollte aber damit arbeiten. $LINENOwird von POSIX angegeben. Auch - setze das Skript nicht im selben Verzeichnis - sonst Änderung des *an *.NEFin den beiden ersten und letzten Zeilen.
Mikeserv
@Seul - wenn $LINENOnicht funktioniert, wird dies wahrscheinlich - versuchen, die erste Zeile zu ändern - stat --printf='}" "%z_${SN}_$((i=i+1)).NEF"\n' -- *.NEF |... und die letzte Zeile zu ...SN=SHOOTNAME sh -s -- *.NEF
mikeserv
Danke, dass du zurückgekommen bist. Ich habe es mit sh versucht und das funktioniert besser. Allerdings drei Probleme mit Ihrem letzten Code (nach "oder vielleicht"):
Seul
a) Die Dateierweiterung geht verloren
Seul