PDF an Hand des hinterlegten barcodes umbenennen

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Benutzeravatar
Meillo
Moderator
Beiträge: 8818
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: PDF an Hand des hinterlegten barcodes umbenennen

Beitrag von Meillo » 04.04.2022 17:32:53

letzter3 hat geschrieben: ↑ zum Beitrag ↑
04.04.2022 17:27:20
Alles zwischen den Sternchen soll der neue Dateiname werden.
*2022-04-01_20123990*
Die neue Datei soll also 2022-04-01_20123990.pdf heissen.
Dann schlage ich mal folgendes vor:

Code: Alles auswählen

DATEINAME=`sed -n '/^\*20[0-9][0-9]-[0-9][0-9]-[0-9][0-9]_[0-9][0-9]*\*$/ {s/\*//g;p;q;}' "$DATEI"`.pdf
Use ed once in a while!

letzter3
Beiträge: 446
Registriert: 16.07.2011 22:07:31

Re: PDF an Hand des hinterlegten barcodes umbenennen

Beitrag von letzter3 » 04.04.2022 18:08:57

Kann mir jemand erklären, warum dies gemacht wird?
20[0-9][0-9]-[0-9][0-9]-[0-9][0-9]_[0-9][0-9]
Geht nicht sowas wie "Nimm die Zeichen zwischen den beiden Sternchen."

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

Re: PDF an Hand des hinterlegten barcodes umbenennen

Beitrag von Meillo » 04.04.2022 18:13:23

letzter3 hat geschrieben: ↑ zum Beitrag ↑
04.04.2022 18:08:57
Kann mir jemand erklären, warum dies gemacht wird?
20[0-9][0-9]-[0-9][0-9]-[0-9][0-9]_[0-9][0-9]
Geht nicht sowas wie "Nimm die Zeichen zwischen den beiden Sternchen."
Natuerlich geht auch das ... nur koennte das auch auf sonstige Zeilen zutreffen, falls im Fliesstext zufaellig mal irgendwo eine Zeile mit einem Stern beginnt und aufhoert. Darum versucht man normalerweise die Angaben so eng wie moeglich zu fassen.

Wobei in dem Fall hier immerhin nach dem ersten Fund schon abgebrochen wird, so dass der weiter untern stehende Fliesstext nicht mehr beruecksichtigt wird.

Aber hier hast du die Holzhammervariante: ;-)

Code: Alles auswählen

DATEINAME=`sed -n '/^\*..*\*$/ {s/\*//g;p;q;}' "$DATEI"`.pdf
Use ed once in a while!

eggy
Beiträge: 3331
Registriert: 10.05.2008 11:23:50

Re: PDF an Hand des hinterlegten barcodes umbenennen

Beitrag von eggy » 04.04.2022 18:36:23

All den RegEchsen da ist gemein, dass nen 13ter Monat sein darf ... für Gehaltszahlungen natürlich nett, bei allem anderen nuja.

Code: Alles auswählen

#!/bin/bash
DATEI=$1
DATEINAME=`grep "^\*20[0-9][0-9]-[0-9][0-9]-[0-9][0-9]_.*\*$" $DATEI| head -1`
OLDIFS=$IFS
IFS='_-*'
arr=($DATEINAME)
Y=${arr[1]}
M=${arr[2]}
D=${arr[3]}
echo $Y " " $M " " $D

# hier noch auf plausibilität prüfen
#
# ....

# dann das verschieben 
# echo rausnehmen, wenn es so aussieht, als sei es das, was es werden soll
# ich halte es ohne pruefung aber fuer ungut
echo mv -n ${DATEI} /dahin/${Y}-${M}-${D}_${DATEI}.pdf

IFS=$OLDIFS
@bashfreunde: spricht (abgesehn davon, dass es schlimmes Chaos geben kann,} hier was gegen ${}?
Und mit Pfaden im übergebenen Dateinamen kommt das so auch noch nicht klar, da gabs doch von den built-in-bash Funktionen was für "nur den Dateinamenteil ohne Pfadrest", ich komm grad nicht auf den Namen, wie hieß das nochmal? Nicht Basepath, so ähnlich ...
oder muss man da wieder mit IFS und letzter arraypart rumtricksen?
Ich merk immer wieder, bashscripts sind nen einziger Krampf. awk und c++ sind so viel angenehmer

JTH
Moderator
Beiträge: 3023
Registriert: 13.08.2008 17:01:41
Wohnort: Berlin

Re: PDF an Hand des hinterlegten barcodes umbenennen

Beitrag von JTH » 04.04.2022 18:53:52

eggy hat geschrieben: ↑ zum Beitrag ↑
04.04.2022 18:36:23
@bashfreunde
Huhu :)

eggy hat geschrieben: ↑ zum Beitrag ↑
04.04.2022 18:36:23
spricht (abgesehn davon, dass es schlimmes Chaos geben kann,} hier was gegen ${}?
Spricht nichts dagegen, nein. Es ist, so wie von dir hier benutzt, an allen außer einer Stelle (und den Arrayzugriffen natürlich) aber auch kein funktionaler Unterschied (höchstens für die Lesbarkeit) zu einem „nackten“ $var. Nur beim ${D}_ braucht man die {}, da $D_ auch gültig wäre und die Variable D_ ansprechen würde.

eggy hat geschrieben: ↑ zum Beitrag ↑
04.04.2022 18:36:23
Und mit Pfaden im übergebenen Dateinamen kommt das so auch noch nicht klar, da gabs doch von den built-in-bash Funktionen was für "nur den Dateinamenteil ohne Pfadrest", ich komm grad nicht auf den Namen, wie hieß das nochmal?
Es gibt keine explizite Funktion dafür. Man kann basename, dirname und co. allerdings mit Parameterexpansion ganz leicht nachbilden. Beispiel:

Code: Alles auswählen

~$ my_basename() { echo "${1##*/}"; }
~$ my_basename /foo/bar/baz.txt
baz.txt

Ich schau mal gerade weiter, was ich hier noch so beitragen kann :)
Manchmal bekannt als Just (another) Terminal Hacker.

eggy
Beiträge: 3331
Registriert: 10.05.2008 11:23:50

Re: PDF an Hand des hinterlegten barcodes umbenennen

Beitrag von eggy » 04.04.2022 19:12:13

Danke. basename wars

Code: Alles auswählen

$ basename /tmp/testdaten.txt.pdf
testdaten.txt.pdf
gehört zu den coreutils ... wie sollte es anders sein :roll:

JTH
Moderator
Beiträge: 3023
Registriert: 13.08.2008 17:01:41
Wohnort: Berlin

Re: PDF an Hand des hinterlegten barcodes umbenennen

Beitrag von JTH » 04.04.2022 20:25:35

eggy hat geschrieben: ↑ zum Beitrag ↑
04.04.2022 19:12:13
Danke. basename wars
Ah, dann hatte ich auch nicht ganz richtig gelesen. Ich meinte, du kamst nicht auf eine reine Shell-„Implementierung“ für basename.

Ich hab mal geschaut, eure Ansätze zum Umbenennen zusammenzutragen. Hoffe, das nimmt nix vorweg oder geht am Ziel vorbei:

Code: Alles auswählen

#!/bin/bash
set -eu -o pipefail

destname_pdftotext()
{
	pdftotext "$1" - | grep -m1 "^\*[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]_.*\*$" | tr -d '*'
}

destname_zbarimg()
{
	zbarimg -q -Sdisable -Scode39.enable <(pdftoppm -png -singlefile "$1")  | cut -d: -f2-  | tr ' ' _
}

: "${method:=zbarimg}"
srcfile=$1
destdir=${2:-/default/destination/dir}
destname=$("destname_$method" "$srcfile").pdf

echo "Would move '$(realpath "$srcfile")' to '${destdir%/}/${destname}'"
#mv -nv -- "$srcfile" "${destdir%/}/${destname}"
Faulerweise tatsächlich als Bash-Skript – zbarimg kann nicht von stdin lesen und <(pdftoppm …) ging schneller, als ein Tempdir anlegen und aufräumen. Zum Scharfschalten ist die letzte Zeile. Durch die set-Zeile sollt das einigermaßen sicher sein, nix ungewolltest zu tun, wenn das Barcode-Erkennen fehlschlägt.

Aufzurufen mit PDF-Datei und – wenn gewünscht optional – dem Zielordner:

Code: Alles auswählen

~$ rename_from_barcode foobar.pdf /some/where/else
Would move '/here/foobar.pdf' to '/some/where/else/2022-03-24_20123988.pdf'
Zum Experimentieren oder so könnt man die andere Methode auswählen:

Code: Alles auswählen

~$ method=pdftotext rename_from_barcode foobar.pdf /some/where/else

Wenn das so manuell tut, was es soll, könnt man gucken, es um inotifywait -e close_write oder so zu erweitern oder das in einem separaten Skript benutzen, um dieses hier aufzurufen.
Zuletzt geändert von JTH am 14.04.2022 21:35:02, insgesamt 1-mal geändert.
Grund: ` | tr ' ' _` bei destname_zbarimg() ergänzt
Manchmal bekannt als Just (another) Terminal Hacker.

eggy
Beiträge: 3331
Registriert: 10.05.2008 11:23:50

Re: PDF an Hand des hinterlegten barcodes umbenennen

Beitrag von eggy » 04.04.2022 20:42:04

Offtopic:
JTH hat geschrieben: ↑ zum Beitrag ↑
04.04.2022 20:25:35
Ah, dann hatte ich auch nicht ganz richtig gelesen. Ich meinte, du kamst nicht auf eine reine Shell-„Implementierung“ für basename.
Ich dachte auch erst, dass das ne bash Sache wäre.
Nur such da mal in dieser Endlosmanpage nach was, von dem du den Namen nicht kennst :twisted:.
Dass das in coreutils steckt, hab ich dann auch erst durch Dein Posting mit "base<tab>" ui ... mal "basetab /irgendwas/mit/pfad/ausprobieren" uiui ... "whereis basename", "apt-file search bin/basename" detektiviert. Also nochmal Danke für Gedächnis anstubsen.
Ich mach um umfangreichere Shellscripte normalerweise einen so weiten Bogen wie nur irgend möglich ... awk, make, notfalls auch Python ... alles, aber bitte nichts, bei dem ich mehr Zeit in die Besonderheiten der Syntax als in das eigentliche Problem investieren muss.
(hatte auch angenommen/gehofft, dass einer der üblichen Verdächtigen den Ball aufnimmt und die eingangs skizzierten Ideen in fertigen Code verwandelt :mrgreen: :THX: )

JTH
Moderator
Beiträge: 3023
Registriert: 13.08.2008 17:01:41
Wohnort: Berlin

Re: PDF an Hand des hinterlegten barcodes umbenennen

Beitrag von JTH » 05.04.2022 12:54:26

eggy hat geschrieben: ↑ zum Beitrag ↑
04.04.2022 20:42:04
Dass das in coreutils steckt, […]
Da stecken sicher noch so einige weniger bekannte Helferlein drin, bei denen es sich lohnen würde, die mal kennen zu lernen. Hast du nach dem RegEx-Kurs schon was vor, Meillo? :wink:
Manchmal bekannt als Just (another) Terminal Hacker.

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

Re: PDF an Hand des hinterlegten barcodes umbenennen

Beitrag von Meillo » 05.04.2022 13:07:04

JTH hat geschrieben: ↑ zum Beitrag ↑
05.04.2022 12:54:26
eggy hat geschrieben: ↑ zum Beitrag ↑
04.04.2022 20:42:04
Dass das in coreutils steckt, […]
Da stecken sicher noch so einige weniger bekannte Helferlein drin, bei denen es sich lohnen würde, die mal kennen zu lernen. Hast du nach dem RegEx-Kurs schon was vor, Meillo? :wink:
Jetzt habe ich ja gerade erst damit begonnen! 8O Ich gehe davon aus, dass der sich schon ein paar Wochen hinziehen wird. Und da sprichst du schon vom naechsten Projekt!? ;-)

Nichts desto trotz, muss ich sagen, dass mir der RE-Kurs jetzt schon gefaellt. Wie auch schon beim Alias-Adventskalender mag ich die laengerdauernde gemeinsame Aktion daran. Das, finde ich, bereichert unser Forum in einer zusaetzlichen Weise. Ich haette also nichts dagegen, sowas oefters/regelmaessig zu machen. Fuer die Coreutils speziell bin ich aber nicht unbedingt die beste Ansprechperson, insbesondere nicht fuer die GNU Coreutils. Ich koennte halt ein paar POSIX Tools beitragen. :-P ;-)

... eigentlich frage ich mich auch, warum gerade du mir die Coreutils zuschieben willst, wo du doch der grosse Kenner in dem Thema bist. Bei dem Script oben im Thread hast du ja auch alle Register gezogen! Ich sag nur:

Code: Alles auswählen

: "${method:=zbarimg}"
Wuerd' mich ja schonmal interessieren, wieviel Prozent der Leser das verstehen. (Aber ein cooles und interessantes Konstrukt ist es alle mal. Vermutlich habe ich das noch nie in einem Shellscript gesehen. :THX: )
Use ed once in a while!

eggy
Beiträge: 3331
Registriert: 10.05.2008 11:23:50

Re: PDF an Hand des hinterlegten barcodes umbenennen

Beitrag von eggy » 05.04.2022 13:36:49

Meillo hat geschrieben: ↑ zum Beitrag ↑
05.04.2022 13:07:04

Code: Alles auswählen

: "${method:=zbarimg}"
Wuerd' mich ja schonmal interessieren, wieviel Prozent der Leser das verstehen.
Ich rate mal: setzt Variable method auf zbarimg und tut sonst garnix?

letzter3
Beiträge: 446
Registriert: 16.07.2011 22:07:31

Re: PDF an Hand des hinterlegten barcodes umbenennen

Beitrag von letzter3 » 05.04.2022 14:33:29

Bitte nicht mit Code erklären weitermachen!
Ich will mich daran selbst versuchen (also verstehen, was warum wo gemacht wird).

eggy
Beiträge: 3331
Registriert: 10.05.2008 11:23:50

Re: PDF an Hand des hinterlegten barcodes umbenennen

Beitrag von eggy » 05.04.2022 15:45:06

letzter3 hat geschrieben: ↑ zum Beitrag ↑
05.04.2022 14:33:29
Bitte nicht mit Code erklären weitermachen!
och menno :(
letzter3 hat geschrieben: ↑ zum Beitrag ↑
05.04.2022 14:33:29
Ich will mich daran selbst versuchen (also verstehen, was warum wo gemacht wird).
:THX:

Sag, wenn Du genug hast. Die Erklärung dürfte auch andere Mitlesende interessieren.
(Thanks @JTH für den Spoiler per PM)

letzter3
Beiträge: 446
Registriert: 16.07.2011 22:07:31

Re: PDF an Hand des hinterlegten barcodes umbenennen

Beitrag von letzter3 » 07.04.2022 00:24:29

Okay, bin zwar müde und wollte mich eigentlich aus Zeitgründen auch erst am WE wieder damit beschäftigen. Aber damit ihr euren Spass habt und ich noch was lerne.
Hier der laienhafte Erklärversuch (geht davon aus, dass ich sämtliche Feinheiten finde :oops: :mrgreen: :oops: 8O )

Code: Alles auswählen

#!/bin/bash
legt die zu verwendende shell fest

Code: Alles auswählen

set -eu -o pipefail
beenden wenn Nicht-Null-Status oder nicht gesetzte Variablen für die Variable pipefail
Verstehe ich nicht. pipefail wird doch nicht definiert?

Code: Alles auswählen

destname_pdftotext()
{
	pdftotext "$1" - | grep -m1 "^\*[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]_.*\*$" | tr -d '*'
}
Hmmm. destname-Erklärung im eigentlichen Sinne nicht gefunden.
Lege Ziel fest->hier die Funktion (?) pdftotext
Wende pdftotext auf das Dokument (welches?) an. Greppe dann bis die Zahl 1 mal gefunden wurde (-m1).
Ratemodus für "^\ -> alles innerhalb der *
Sammle nur Ziffern 0-9, für YYYY-MM-DD
Setze _
es verlässt mich :cry:
Frage: 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

destname_zbarimg()
{
	zbarimg -q -Sdisable -Scode39.enable <(pdftoppm -png -singlefile "$1")  | cut -d: -f2-
}
Lege Ziel fest->hier die Funktion (?) zbarimg
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?

Code: Alles auswählen

: "${method:=zbarimg}"
den : 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

srcfile=$1
Quellfile (ohne Prüfung, ob das überhaupt ein PDF ist?)

Code: Alles auswählen

destdir=${2:-/default/destination/dir}
Zielverzeichnis. Ist von mir zu setzen. Aber bei {2: steig ich aus.

Code: Alles auswählen

destname=$("destname_$method" "$srcfile").pdf
Definition 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

echo "Would move '$(realpath "$srcfile")' to '${destdir%/}/${destname}'"
Schreibe auf den screen, was du tun würdest.
Aber wo kommt jetzt realpath her?

Code: Alles auswählen

#mv -nv -- "$srcfile" "${destdir%/}/${destname}"
Auskommentiert wird das Quell-PDF verschoben in das Zielverzeichnis als PDF mit dem Namen der durch destname=$("destname_$method" "$srcfile").pdf festgelegt wurde.

Okay. Maximal die Hälfte verstanden.
Was mir noch nicht einleuchtet: wo liegt das script? Es wird ja kein Verzeichnis angegeben, in dem "gearbeitet" werden soll.

Kann
a) ein Log erzeugt werden, in dem stumpf die Umwandlung dokumentiert wird?
b) eine Warnmeldung per mailx bei Abbruch versandt werden?

letzter3
Beiträge: 446
Registriert: 16.07.2011 22:07:31

Re: PDF an Hand des hinterlegten barcodes umbenennen

Beitrag von letzter3 » 07.04.2022 21:13:32

War meine Interpretation so gut, dass nichts mehr hinzuzufügen wäre oder so schlecht, das Hopfen und Malz verloren scheinen?

eggy
Beiträge: 3331
Registriert: 10.05.2008 11:23:50

Re: PDF an Hand des hinterlegten barcodes umbenennen

Beitrag von eggy » 07.04.2022 21:22:07

Ich überlass das lieber JTH, wer den Schaden anrichtet, muss auch aufräumen :mrgreen:

JTH
Moderator
Beiträge: 3023
Registriert: 13.08.2008 17:01:41
Wohnort: Berlin

Re: PDF an Hand des hinterlegten barcodes umbenennen

Beitrag von JTH » 07.04.2022 21:46:59

Na danke, eggy :lol:

Ich bin grad unterwegs und hab erst Sonntagabend wieder Gelegenheit, richtig zu antworten. Größere Beiträge sind am Handy doch etwas aufwendig. Antworte dann gerne nochmal ausführlich :)
Manchmal bekannt als Just (another) Terminal Hacker.

eggy
Beiträge: 3331
Registriert: 10.05.2008 11:23:50

Re: PDF an Hand des hinterlegten barcodes umbenennen

Beitrag von eggy » 07.04.2022 22:02:49

@letzter3: Damit das Warten auf den Weihnachtsmann, aehm auf den JTH nicht zu langweilig wird:
letzter3 hat geschrieben: ↑ zum Beitrag ↑
07.04.2022 00:24:29
Aber wo kommt jetzt realpath her?

Code: Alles auswählen

whereis realpath
which realpath
und mit "apt-file search realpath | grep bin" bekommst dann auch noch erzählt aus welchem Paket das stammt.

tobo
Beiträge: 1995
Registriert: 10.12.2008 10:51:41

Re: PDF an Hand des hinterlegten barcodes umbenennen

Beitrag von tobo » 07.04.2022 23:35:38

Oder einfacher

Code: Alles auswählen

apt-file search bin/realpath

letzter3
Beiträge: 446
Registriert: 16.07.2011 22:07:31

Re: PDF an Hand des hinterlegten barcodes umbenennen

Beitrag von letzter3 » 10.04.2022 20:03:01

JTH hat geschrieben: ↑ zum Beitrag ↑
07.04.2022 21:46:59
Na danke, eggy :lol:

Ich bin grad unterwegs und hab erst Sonntagabend wieder Gelegenheit, richtig zu antworten. Größere Beiträge sind am Handy doch etwas aufwendig. Antworte dann gerne nochmal ausführlich :)
Ich würde mich freuen.

JTH
Moderator
Beiträge: 3023
Registriert: 13.08.2008 17:01:41
Wohnort: Berlin

Re: PDF an Hand des hinterlegten barcodes umbenennen

Beitrag von JTH » 14.04.2022 22:19:39

letzter3 hat geschrieben: ↑ zum Beitrag ↑
07.04.2022 00:24:29
(geht davon aus, dass ich sämtliche Feinheiten finde :oops: :mrgreen: :oops: 8O )
Soo, etwas verspätet dann noch ein paar Erklärungen. Ich hoffe, ich sorge nicht für noch mehr Verwirrung ;)

letzter3 hat geschrieben: ↑ zum Beitrag ↑
07.04.2022 00:24:29

Code: Alles auswählen

#!/bin/bash
legt die zu verwendende shell fest
Hmm, in gewisser Weise, ja. Man kann ein Shellskript auch immer ohne diese erste Zeile als

Code: Alles auswählen

~$ sh mein_skript
~$ bash mein_skript
ausführen. Dann muss man aber wissen, welche Shell (häufige Frage: Bash oder nicht Bash) das Skript braucht. Macht man ein Skript ausführbar (z.B. mit chmod +x) und zusammen mit dieser ersten Shebang-Zeile übernimmt dann das Betriebssystem das Aufrufen der angegebenen Shell. Und übergibt dieser den Namen des abzuarbeitenden Skripts. Das Skript wird dann äquivalent zu den beiden obigen Zeilen aufgerufen, man kann es wie ein „richtiges“ Programm verwenden:

Code: Alles auswählen

~$ ./mein_skript
Die Shebang-Zeile ist nicht nur für Shellskripte relevant, sondern auch Python, Perl, awk, manchmal Makefiles etc. etc. Prinzipiell kann man in der Shebang-Zeile ein beliebiges Programm – einen Interpreter für diese (Skript-) Datei – angeben, das aufgerufen wird und den Namen der (Skript-)Datei übergeben bekommt.


letzter3 hat geschrieben: ↑ zum Beitrag ↑
07.04.2022 00:24:29

Code: Alles auswählen

set -eu -o pipefail
beenden wenn Nicht-Null-Status oder nicht gesetzte Variablen für die Variable pipefail
Verstehe ich nicht. pipefail wird doch nicht definiert?
pipefail ist eine Option, die keine Kurzform wie das -e und -u hat. Was sie bewirkt, verrät dir

Code: Alles auswählen

~$ help set
Ich hatte sie hier gesetzt, damit (in Kombination mit -e) das ganze Skript fehlschlägt, wenn in den beiden Funktionen zum Umwandeln von PDF zu Text etwas scheitert. (Die beide eine Pipeline … | … benutzen.)

letzter3 hat geschrieben: ↑ zum Beitrag ↑
07.04.2022 00:24:29

Code: Alles auswählen

destname_pdftotext()
Hmmm. destname-Erklärung im eigentlichen Sinne nicht gefunden.
Das ist einfach eine Funktionsdefinition, „destname_pdftotext“ ist der volle Funktionsname. Man kann es auch als

Code: Alles auswählen

function destname_pdftotext()
schreiben, aber das ist Bash-spezifisch und m.M.n. unnötig viel zu tippen. Die Funktion würde in anderen Sprachen ganz grob so aussehen, vielleicht hilfts mit Signatur:

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

letzter3 hat geschrieben: ↑ zum Beitrag ↑
07.04.2022 00:24:29

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 '*'
}
Wende pdftotext auf das Dokument (welches?) an. Greppe dann bis die Zahl 1 mal gefunden wurde (-m1).
Ratemodus für "^\ -> alles innerhalb der *
Sammle nur Ziffern 0-9, für YYYY-MM-DD
Setze _
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:

Code: Alles auswählen

destname_pdftotext "/somewhere/over/the/rainbow.pdf"
In anderen Sprachen wäre das Argument oft in Klammern, hier nicht. Das Argument wird dann über $1 verwendet, da es das 1. Funktionsargument ist. Die Funktionsargumente werden in Skripten nicht per Namen (wie das pdf_path in den drei Beispielen oben), sondern nur über ihre Position beim Funktionsaufruf angesprochen.

Code: Alles auswählen

pdftotext "$1" -
In der Funktion wird also als erstes pdftotext mit der PDF-Datei aufgerufen. Das Minus als zweites Argument ist eine oft benutzte Konvention, die dem Programm sagt, dass es sein Ergebnis nicht in eine Datei schreiben soll, sondern direkt auf die Standardausgabe. pdftotext kann das praktischerweise auch. Damit spart man sich hier eine temporäre Datei, die man anschließend wieder löschen müsste.

Code: Alles auswählen

… | grep -m1 "^\*[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]_.*\*$"
Die Ausgabe von pdftotext – der Text des PDFs – wird über eine Pipe | direkt an grep weitergegeben. Deshalb sieht man die Ausgabe von pdftotext auch nicht tatsächlich auf dem Bildschirm. Den Suchausdruck hatte ich, meine ich, von euren vorherigen Schritten kopiert. Genau, das -m1 sorgt dafür, dass höchstens ein grep-Ergebnis weitergegeben wird. Ähnlich wie ein head -1, was im Thread auch auftauchte. Ist ein Baustein, um fehlerhafte Umbenennungen auszuschließen.

Code: Alles auswählen

… | tr -d '*'
Das tr entfernt abschließend noch die Sternchen vorne und hinten, die Zeile im PDF sah ja so aus: *2022-03-24_20123988*. Und ohne die Sternchen ist es ja praktischerweise direkt der Zieldateiname. (Oder hab ich dabei was übersehen?)

letzter3 hat geschrieben: ↑ zum Beitrag ↑
07.04.2022 00:24:29
es verlässt mich :cry:
Dran bleiben! ;)

letzter3 hat geschrieben: ↑ zum Beitrag ↑
07.04.2022 00:24:29
Frage: 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?
Fast. [:digit:] ersetzt ein 0-9. Man müsste also (außerdem mit zwei [[ … ]], warum, erklärt Meillo bestimmt parallel bald :D )

Code: Alles auswählen

[[:digit:]][[:digit:]][[:digit:]][[:digit:]]-[[:digit:]][[:digit:]]-[[:digit:]][[:digit:]]
schreiben, was gleich nicht mehr unbedingt kürzer ist.
grep kennt auch eine Angabe, wie oft sich ein Ausdruck wiederholen soll

Code: Alles auswählen

grep -E '[[:digit:]]{4}-[[:digit:]]{2}-[[:digit:]]{2}'
aber auch da wäre [0-9], statt [[:digit:]] kürzer und wohl auch übersichtlicher.

letzter3 hat geschrieben: ↑ zum Beitrag ↑
07.04.2022 00:24:29

Code: Alles auswählen

destname_zbarimg()
{
	zbarimg -q -Sdisable -Scode39.enable <(pdftoppm -png -singlefile "$1")  | cut -d: -f2-
}
Lege Ziel fest->hier die Funktion (?) zbarimg
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?
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.

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 …)
Das erreicht das gleiche wie das, was du weiter oben schon mit einer temporären PNG-Datei ausprobiert hattest (leicht von mir umformatiert):
letzter3 hat geschrieben: ↑ zum Beitrag ↑
02.04.2022 14:06:11

Code: 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
letzter3 hat geschrieben: ↑ zum Beitrag ↑
02.04.2022 14:06:11

Code: Alles auswählen

CODE-39:2022-03-24 20123988
Das

Code: Alles auswählen

… | cut -d: -f2-
sorgt am Ende nur dafür, dass das CODE-39: weggeschnitten wird. cut unterteilt die Zeile in einzelne Felder, als Trennzeichen (delimiter) wird : angegeben. Man hat also „CODE-39“ und „2022-03-24 20123988“ und möchte davon jetzt nur das 2. Feld haben: -f2-. Das Minus hinter der 2 war eigentlich überflüssig, es besagt „2. Feld und alle folgenden“ – es gibt ja keine weiteren.

Ergänzung: An der Stelle hab ich den Ursprungsbeitrag gerade noch ergänzt und ein

Code: Alles auswählen

… | tr ' ' _
angehängt. Das ersetzt das eine Leerzeichen im „2022-03-24 20123988“ durch den gewünschten Unterstrich.


letzter3 hat geschrieben: ↑ zum Beitrag ↑
07.04.2022 00:24:29

Code: Alles auswählen

: "${method:=zbarimg}"
den : 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.
Da war ich etwas übermütig :lol: 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:

Code: Alles auswählen

if [ -z "$method" ]; then
    method=zbarimg
fi
: ist ein Kommando, das einfach nichts macht, siehe help :. Kann man als Platzhalter oder zum Verwerfen von Dingen benutzen. Die Syntax

Code: Alles auswählen

${variable:=wert}
weist variable den Wert wert zu, wenn variable ungesetzt oder null ist. Das Konstrukt gibt allerdings den Wert von variable auch zurück, deshalb verwirft man ihn mit dem :.

letzter3 hat geschrieben: ↑ zum Beitrag ↑
07.04.2022 00:24:29

Code: Alles auswählen

srcfile=$1
Quellfile (ohne Prüfung, ob das überhaupt ein PDF ist?)
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: ↑ zum Beitrag ↑
07.04.2022 00:24:29

Code: Alles auswählen

destdir=${2:-/default/destination/dir}
Zielverzeichnis. Ist von mir zu setzen. Aber bei {2: steig ich aus.
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:

Code: Alles auswählen

~$ das_skript ein.pdf
~$ das_skript ein.pdf /der/zielordner
Hatte ich mehr zum Ausprobieren so geschrieben, am Ende reicht dir vielleicht

Code: Alles auswählen

destdir=/hier/oder/dort

letzter3 hat geschrieben: ↑ zum Beitrag ↑
07.04.2022 00:24:29

Code: Alles auswählen

destname=$("destname_$method" "$srcfile").pdf
Definition 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.
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.

Code: Alles auswählen

"destname_$method" "$srcfile"
ist wieder eine Abkürzung, um abhängig vom method-Inhalt die richtige Funktion aufzurufen. Ausgeschrieben wäre es:

Code: Alles auswählen

if [ "$method" = pdftotext ]; then
    destname_pdftotext "$srcfile"
elif ["$method" = zbarimg ]; then
    destname_zbarimg "$srcfile"
fi
Der Name eines aufzurufenden Kommandos kann nämlich auch einfach in einer Variablen stehen:

Code: Alles auswählen

#!/bin/sh
some_variable=less
$some_variable ~/.bashrc

letzter3 hat geschrieben: ↑ zum Beitrag ↑
07.04.2022 00:24:29

Code: Alles auswählen

echo "Would move '$(realpath "$srcfile")' to '${destdir%/}/${destname}'"
Schreibe auf den screen, was du tun würdest.
Ja, genau. Einfach zum Ausprobieren für dich (und mich vorher).
letzter3 hat geschrieben: ↑ zum Beitrag ↑
07.04.2022 00:24:29
Aber wo kommt jetzt realpath her?
Das ist ein Kommando aus den Debiancoreutils. Es gibt dir zu einem Dateipfad den absoluten Pfad aus:

Code: Alles auswählen

~$ realpath Documents/some.pdf
/home/letzter3/Documents/some.pdf
War hier nur zu kosmetischen Zwecken verwendet.

letzter3 hat geschrieben: ↑ zum Beitrag ↑
07.04.2022 00:24:29

Code: Alles auswählen

#mv -nv -- "$srcfile" "${destdir%/}/${destname}"
Auskommentiert wird das Quell-PDF verschoben in das Zielverzeichnis als PDF mit dem Namen der durch destname=$("destname_$method" "$srcfile").pdf festgelegt wurde.
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 :mrgreen: )

letzter3 hat geschrieben: ↑ zum Beitrag ↑
07.04.2022 00:24:29
Was mir noch nicht einleuchtet: wo liegt das script? Es wird ja kein Verzeichnis angegeben, in dem "gearbeitet" werden soll.
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.

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
rename_from_barcode wäre z.B. ein Name der sich anbietet. Ich würde das Skript wahrscheinlich nach /usr/local/bin tun, also /usr/local/bin/rename_from_barcode.

letzter3 hat geschrieben: ↑ zum Beitrag ↑
07.04.2022 00:24:29
Kann
a) ein Log erzeugt werden, in dem stumpf die Umwandlung dokumentiert wird?
b) eine Warnmeldung per mailx bei Abbruch versandt werden?
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.

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 :lol:
Manchmal bekannt als Just (another) Terminal Hacker.

eggy
Beiträge: 3331
Registriert: 10.05.2008 11:23:50

Re: PDF an Hand des hinterlegten barcodes umbenennen

Beitrag von eggy » 15.04.2022 13:49:38

Da Meillos Kurs zur Vermeidung lokaler Keksanhäufung außer Konkurrenz läuft, geht der Erklärkeks der Woche diesmal wohl an JTH. :THX:

JTH
Moderator
Beiträge: 3023
Registriert: 13.08.2008 17:01:41
Wohnort: Berlin

Re: PDF an Hand des hinterlegten barcodes umbenennen

Beitrag von JTH » 15.04.2022 17:05:24

:oops: :lol:
Manchmal bekannt als Just (another) Terminal Hacker.

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

Re: PDF an Hand des hinterlegten barcodes umbenennen

Beitrag von Meillo » 16.04.2022 07:56:26

Da mache ich doch gerne die Keksdose auf und ueberreiche dir einen DFDE-Keks:
Bild
Use ed once in a while!

letzter3
Beiträge: 446
Registriert: 16.07.2011 22:07:31

Re: PDF an Hand des hinterlegten barcodes umbenennen

Beitrag von letzter3 » 17.04.2022 13:42:49

JTH hat geschrieben: ↑ zum Beitrag ↑
14.04.2022 22:19:39
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.
Hier die Ergebnisse der Standardfunktion:

Code: Alles auswählen

~/barcode ./rename_from_barcode.sh 1.pdf
Would move '/home/letzter/barcode/1.pdf' to '/default/destination/dir/2022-04-07_VR-789.pdf'
gesetztes DestDir

Code: Alles auswählen

~/barcode ./rename_from_barcode.sh 1.pdf
Would move '/home/letzter/barcode/1.pdf' to '/home/letzter/barcode/test/2022-04-07_VR-789.pdf'
letzte # entfernt, DestDir ist nicht vorhanden

Code: Alles auswählen

~/barcode ./rename_from_barcode.sh 1.pdf
Would move '/home/letzter/barcode/1.pdf' to '/home/letzter/barcode/test/2022-04-07_VR-789.pdf'
~/barcode mv: das Verschieben von '1.pdf' nach '/home/letzter/barcode/test/2022-04-07_VR-789.pdf' ist nicht möglich: Datei oder Verzeichnis nicht gefunden

Code: Alles auswählen

~/barcode mkdir test
~/barcode ./rename_from_barcode.sh 1.pdf
Would move '/home/letzter/barcode/1.pdf' to '/home/letzter/barcode/test/2022-04-07_VR-789.pdf'
Datei umbenannt '1.pdf' -> '/home/letzter/barcode/test/2022-04-07_VR-789.pdf'
~/barcode cd test
~/barcode/test ls
2022-04-07_VR-789.pdf
Fehler provozieren, 1.txt ist nicht vorhanden

Code: Alles auswählen

./rename_from_barcode.sh 1.txt
zsh: datei oder Verzeichnis nicht gefunden: ./rename_from_barcode.sh
Frage: Warum meldet sich hier zsh (ist gerade ein manjaro) und nicht die bash?

Fehler provozieren, kein Barcode im PDF, PDF ist aber vorhanden

Code: Alles auswählen

~/barcode ./rename_from_barcode.sh ./rename_from_barcode.sh Unbenannt1.pdf
I/O Error: Couldn't open file 'Unbenannt1.pdf': No such file or directory.
ERROR: no decode delegate for this image format `' @ error/constitute.c/ReadImage/737

Code: Alles auswählen

cat rename_from_barcode.sh
#!/bin/bash
set -eu -o pipefail

destname_pdftotext()
{
        pdftotext "$1" - | grep -m1 "^\*[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]_.*\*$" | tr -d '*'
}

destname_zbarimg()
{
        zbarimg -q -Sdisable -Scode39.enable <(pdftoppm -png -singlefile "$1")  | cut -d: -f2-  | tr ' ' _
}

: "${method:=zbarimg}"
srcfile=$1
destdir=${2:-/home/letzter/barcode/test}
destname=$("destname_$method" "$srcfile").pdf

echo "Would move '$(realpath "$srcfile")' to '${destdir%/}/${destname}'"
mv -nv -- "$srcfile" "${destdir%/}/${destname}"
Macht also erstmal, was es soll.

Antworten