Soo, etwas verspätet dann noch ein paar Erklärungen. Ich hoffe, ich sorge nicht für noch mehr Verwirrungletzter3 hat geschrieben:07.04.2022 00:24:29(geht davon aus, dass ich sämtliche Feinheiten finde )
Hmm, in gewisser Weise, ja. Man kann ein Shellskript auch immer ohne diese erste Zeile alsletzter3 hat geschrieben:07.04.2022 00:24:29legt die zu verwendende shell festCode: Alles auswählen
#!/bin/bash
Code: Alles auswählen
~$ sh mein_skript
~$ bash mein_skript
Code: Alles auswählen
~$ ./mein_skript
pipefail ist eine Option, die keine Kurzform wie das -e und -u hat. Was sie bewirkt, verrät dirletzter3 hat geschrieben:07.04.2022 00:24:29beenden wenn Nicht-Null-Status oder nicht gesetzte Variablen für die Variable pipefailCode: Alles auswählen
set -eu -o pipefail
Verstehe ich nicht. pipefail wird doch nicht definiert?
Code: Alles auswählen
~$ help set
Das ist einfach eine Funktionsdefinition, „destname_pdftotext“ ist der volle Funktionsname. Man kann es auch alsletzter3 hat geschrieben:07.04.2022 00:24:29Hmmm. destname-Erklärung im eigentlichen Sinne nicht gefunden.Code: Alles auswählen
destname_pdftotext()
Code: Alles auswählen
function destname_pdftotext()
Code: Alles auswählen
# C++
std::string destname_pdftotext(const std::string& pdf_path);
# C
int destname_pdftotext(const char *pdf_path, char *str, size_t len);
# Python
def destname_pdftotext(pdf_path: str) -> str
Das ist nun der Inhalt der Funktion und mehr oder weniger die einzelnen Schritte zusammengeschrieben, die ihr vorher schon ausprobiert hattet. Beide Funktionen hier werden (weiter unten) mit dem Pfad einer PDF-Datei als Argument aufgerufen:letzter3 hat geschrieben:07.04.2022 00:24:29Wende pdftotext auf das Dokument (welches?) an. Greppe dann bis die Zahl 1 mal gefunden wurde (-m1).Code: Alles auswählen
{ pdftotext "$1" - | grep -m1 "^\*[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]_.*\*$" | tr -d '*' }
Ratemodus für "^\ -> alles innerhalb der *
Sammle nur Ziffern 0-9, für YYYY-MM-DD
Setze _
Code: Alles auswählen
destname_pdftotext "/somewhere/over/the/rainbow.pdf"
Code: Alles auswählen
pdftotext "$1" -
Code: Alles auswählen
… | grep -m1 "^\*[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]_.*\*$"
Code: Alles auswählen
… | tr -d '*'
Dran bleiben!
Fast. [:digit:] ersetzt ein 0-9. Man müsste also (außerdem mit zwei [[ … ]], warum, erklärt Meillo bestimmt parallel bald )letzter3 hat geschrieben:07.04.2022 00:24:29Frage: kann anstelle von [0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] auch [:digit:]-[:digit:]-[:digit:] verwendet werden?
Code: Alles auswählen
[[:digit:]][[:digit:]][[:digit:]][[:digit:]]-[[:digit:]][[:digit:]]-[[:digit:]][[:digit:]]
grep kennt auch eine Angabe, wie oft sich ein Ausdruck wiederholen soll
Code: Alles auswählen
grep -E '[[:digit:]]{4}-[[:digit:]]{2}-[[:digit:]]{2}'
Wiederum eine Funktion, mit Namen „destname_zbarimg“, die diesmal (offensichtlich) zbarimg benutzt und wieder hauptsächlich die vorher im Thema ausprobierten Einzelschritte kombiniert. Die Optionen für zbarimg und pdftoppm sind einfach übernommen. Bei zbarimg explizit nur Code 39 zu aktivieren kann mögliche Falscherkennungen anderer Codes vorbeugen, denke ich.letzter3 hat geschrieben:07.04.2022 00:24:29Lege Ziel fest->hier die Funktion (?) zbarimgCode: Alles auswählen
destname_zbarimg() { zbarimg -q -Sdisable -Scode39.enable <(pdftoppm -png -singlefile "$1") | cut -d: -f2- }
Wende zbarimg an auf den input, der von pdftoppm kommt. Verwende keinen Barcode->verwende code39 und gebe nur das Barcode-Ergebnis aus.
pdftoppm erzeugt ein PNG und wandelt nur die erste Seite in ein png.
Benutze (nach zbarimg???) einen TRENNER anstelle des Tabulators und nur für die Felder 2 (???)
Also gib nur die 2 gefundenen (Datum _ Variable) aus?
Ich habe aber wieder einen „Trick“ benutzt, um keine temporäre, von pdftoppm produzierte PNG-Datei zu haben, die man löschen müsste. pdftoppm bekommt keinen Zieldateinamen übergeben – sondern nur die Quell-PDF-Datei in $1 – und schreibt sein Ergebnis (die Bits einer PNG-Datei) damit auf die Standardausgabe. Folgende Syntax sorgt dafür, dass die Bash (geht nur mit der) automatisch selbst dafür sorgt, dass diese Standardausgabe an zbarimg wie eine Datei übergeben wird:
Code: Alles auswählen
zbarimg … <(pdftoppm …)
letzter3 hat geschrieben:02.04.2022 14:06:11Code: Alles auswählen
pdftoppm -png -singlefile some.pdf tmp zbarimg -q -Scode39.enable tmp.png
Die Ausgabe von zbarimg ist für die relevanten PDFs ja anscheinend
Das
Code: Alles auswählen
… | cut -d: -f2-
Ergänzung: An der Stelle hab ich den Ursprungsbeitrag gerade noch ergänzt und ein
Code: Alles auswählen
… | tr ' ' _
Da war ich etwas übermütig und die method-Variable/-Auswahl an sich mag für dein Problem am Ende auch überflüssiug sein. Diese Zeile weist der Variablen den Standardwert „zbarimg“ zu, wenn die Variable noch ungesetzt/null oder leer ist. Lang – aber nicht 100% äquivalent! – ausgeschrieben:letzter3 hat geschrieben:07.04.2022 00:24:29den : hab ich auf die Schnelle nur als "application" in der bash gefunden. Die englische Erklärung ist mir aber zu hoch. Setze incl. in der Methode (hier->zbarimg) verwendeten Variablen und führe aus? Würde dann mit dem destname korrespondieren.Code: Alles auswählen
: "${method:=zbarimg}"
Code: Alles auswählen
if [ -z "$method" ]; then
method=zbarimg
fi
Code: Alles auswählen
${variable:=wert}
Das $1 ist hier des erste Argument, das dem Skript übergeben wurde. Da das noch keine Komplettlösung sein sollte, hab ich da keine weitere Prüfung eingebaut. Aber hast recht, das sollte man sicher irgendwo noch machen.letzter3 hat geschrieben:07.04.2022 00:24:29Quellfile (ohne Prüfung, ob das überhaupt ein PDF ist?)Code: Alles auswählen
srcfile=$1
Eine andere Variante für Standardwertzuweisung, wenn ungesetzt. Nur das hier der Inhalt des zweiten Skriptarguments, $2, angeguckt wird und wenn leer oder nicht angegeben der Vorgabewert /default/destination/dir der Variablen destdir zugewiesen wird. Anderfalls wird der Inhalt von $2 dem destdir zugewiesen. Du kannst das Skript also mit oder ohne aufrufen:letzter3 hat geschrieben:07.04.2022 00:24:29Zielverzeichnis. Ist von mir zu setzen. Aber bei {2: steig ich aus.Code: Alles auswählen
destdir=${2:-/default/destination/dir}
Code: Alles auswählen
~$ das_skript ein.pdf
~$ das_skript ein.pdf /der/zielordner
Code: Alles auswählen
destdir=/hier/oder/dort
Hier wird eine der beiden oben definierten Funktionen aufgerufen, abhängig von gesetzter method. Die Ausgabe beider Funktionen ist so zurechtgeschnitten, wie oben beschrieben, dass sie genau der gesuchte Zieldateiname ist, plus das hier noch angehängte .pdf.letzter3 hat geschrieben:07.04.2022 00:24:29Definition des künftigen Namens in Abhängigkeit der verwendeten Methode. Defaultmäßig also des outputs von cut -d: -f2-, nachdem zbarimg an dem Quellfile rumgewurschtelt hat.Code: Alles auswählen
destname=$("destname_$method" "$srcfile").pdf
Code: Alles auswählen
"destname_$method" "$srcfile"
Code: Alles auswählen
if [ "$method" = pdftotext ]; then
destname_pdftotext "$srcfile"
elif ["$method" = zbarimg ]; then
destname_zbarimg "$srcfile"
fi
Code: Alles auswählen
#!/bin/sh
some_variable=less
$some_variable ~/.bashrc
Ja, genau. Einfach zum Ausprobieren für dich (und mich vorher).letzter3 hat geschrieben:07.04.2022 00:24:29Schreibe auf den screen, was du tun würdest.Code: Alles auswählen
echo "Would move '$(realpath "$srcfile")' to '${destdir%/}/${destname}'"
Das ist ein Kommando aus den coreutils. Es gibt dir zu einem Dateipfad den absoluten Pfad aus:
Code: Alles auswählen
~$ realpath Documents/some.pdf
/home/letzter3/Documents/some.pdf
Genau, # entfernen und das Verschieben würde, nach obigem echo, tatsächlich ausgeführt. Wenn ich keinen Quatsch gemacht hab, dann so wie du es in deinen Beiträgen beschrieben hast. (Gut, dass dir hier das ${destdir%/} nicht aufgefallen ist. Deshalb schreib ich jetzt auch nix mehr dazu )letzter3 hat geschrieben:07.04.2022 00:24:29Auskommentiert wird das Quell-PDF verschoben in das Zielverzeichnis als PDF mit dem Namen der durch destname=$("destname_$method" "$srcfile").pdf festgelegt wurde.Code: Alles auswählen
#mv -nv -- "$srcfile" "${destdir%/}/${destname}"
Was ich vielleicht mehr am Anfang meines Romans hier hätte schreiben sollen: Das Skript war erstmal nur als Zusammenfassung deiner und eggys Versuchsschritte vorher gedacht. Es fehlt – offensichtlich, hoffe ich – noch der automatisierte Aufruf durch inotify, cron oder den Hausmeister. Wenn ich mich richtig erinnere, sollte das Skript gelegentlich auch manuell aufgerufen werden (?) (grad keine Lust mehr, zu suchen …). Dann würde es sich anbieten, dieses Umbenennen so als eigenständiges Skript zu halten und das autmatisierte Aufrufen separat zu lösen – und dieses Skript dort heraus aufzurufen.letzter3 hat geschrieben:07.04.2022 00:24:29Was mir noch nicht einleuchtet: wo liegt das script? Es wird ja kein Verzeichnis angegeben, in dem "gearbeitet" werden soll.
Aber zu der Frage: Du kannst es hinlegen, wo du möchtest. Temporäre Dateien sind vermieden, wie beschrieben (die landen also nicht irgendwo, da es keine gibt). Das Zielverzeichnis kann dem Skript übergeben oder fest definiert werden. Und an die PDF-Dateien kommt es heran, indem ihre Pfade sinnvoll übergeben werden. Wenn es also automatisiert aufgerufen würde, wären das sehr wahrscheinlich sowieso absolute Pfade:
Code: Alles auswählen
rename_from_barcode /some/samba/share/1970-01-01-00-00-00.pdf
Ja, ein Log wär nicht schwer. Man könnte einfach das echo nach /var/log/irgendwo umleiten oder logger benutzen. Mail verschicken ebenso, da kenn ich mich aber mit dem üblichen Werkzeugen nicht aus. Beides würde ich instinktiv und aus Erfahrung eher in der evtl. separaten Automatisierung machen, nicht hier direkt.letzter3 hat geschrieben:07.04.2022 00:24:29Kann
a) ein Log erzeugt werden, in dem stumpf die Umwandlung dokumentiert wird?
b) eine Warnmeldung per mailx bei Abbruch versandt werden?
Wenn ich das so vorschlagen darf, du hattest ja geschrieben, dass du dich Ostern damit wieder beschäftigen willst: Du könntest ausprobieren, ob meine „Zusammenfassung“ die richtigen Zieldateinamen produziert, falls wichtig mit beiden Methoden.
So, Bierchen ist leer, das muss erstmal reichen