Ich versuche, einige Dokumente in situ zu OCR (über eine Linux-Befehlszeile auf einer Windows-Freigabe). Der Prozess des OCRing ist find und ich habe mich mit dem Befehl find verwirrt, um die Dateien korrekt durch die Schleife zu leiten.
Ich muss jedoch den ursprünglichen Zeitstempel für Änderungen beibehalten. Ich versuche derzeit, stat und touch wie folgt zu verwenden:
#!/bin/bash
OLDIFS=$IFS
IFS=$(echo -en "\n\b")
for f in `find /mnt/library/Libra/Libra/Ashfords -name "*.pdf"`
do
ORIGTS=`stat -c "%Y" $f`
sudo /opt/ABBYYOCR9/abbyyocr9 -rl English -pi -if $f -f PDFA -paemImageOnText -pafpr original -of $f
touch -t $ORIGTS $f
done
IFS=$OLDIFS
Natürlich schlägt der Touch-Befehl fehl. Wenn ich die Befehle separat ausführe, stelle ich fest, dass "stat -c" ungefähr so aussieht:
1334758696
Das ist wie kein Datum, das ich kenne. Ich habe das Gefühl, nah dran zu sein, kann aber nicht herausfinden, wie ich das Datum, das ich habe, in eine berührungsfreundliche Version umwandeln kann. Ist es eine Form von Sekunden von etwas?
IFS
scheint ungewöhnlich. Wollten Sie wirklich auf backspace (\b
) teilen ? Einige Tipps finden Sie unter unix.stackexchange.com/questions/9496/… .Antworten:
stat's
Die Ausgabe ist ein Unix-Zeitstempel, der seit der Epoche auch als Sekunden bezeichnet wird .Bei allen GNU-Coreutils, die ein Datum akzeptieren, können Sie stattdessen einen Zeitstempel setzen, indem Sie dem Zeitstempel einen voranstellen
@
.Also versuch das mal
Siehe coreutils - Sekunden seit der Epoche
quelle
touch
kann den Zeitstempel einer Datei mit dieser-r
Option verwenden. Möglicherweise möchten Sie in eine andere Datei ausgeben (ich gehe davon aus, dass-if
es sich unten um eine Eingabedatei und-of
eine Ausgabedatei handelt).quelle
stat
.Da Sie eine Shell mit annehmen
echo -e
und ohnehin Bash in Ihrer Shebang-Linie haben, können Sie verwendenIFS=$'\n\b'
. Rücktaste zu einem Trennzeichen zu machen ist ziemlich seltsam. Sie brauchenIFS
sowieso nicht für das, was Sie tun.Beachten Sie, dass dadurch der alte Wert von
IFS
nur wiederhergestellt wird, wenn erIFS
ursprünglich festgelegt wurde. Wenn diesIFS
ursprünglich nicht festgelegt wurdeIFS
, wird die leere Zeichenfolge festgelegt, die völlig anders ist. Wenn Sie in ksh, bash oder zshIFS
vorübergehend festlegen müssen , können Sie Ihren Code in eine Funktion schreiben undIFS
diese Funktion lokalisieren. In anderen Schalen müssen Sie vorsichtig mit dem nicht eingestellten Fall sein.Verwenden Sie niemals die Befehlssubstitution für die Ausgabe von
find
.$IFS
. Wenn SieIFS
eine neue Zeile festlegen, wird die Ausgabe in Zeilenumbrüche aufgeteilt, Sie können jedoch weiterhin keine Dateinamen verarbeiten, die Zeilenumbrüche enthalten.A[12].pdf
,A1.pdf
undA2.pdf
, werden Sie am Ende mitA1.pdf A2.pdf A1.pdf A2.pdf
. Sie können das Globbing mitset -f
(und wieder mitset +f
) aktivieren , aber hier (wie meistens) besteht der richtige Weg darin, keine Befehlssubstitution zu verwenden.Verwenden Sie das
-exec
Argument fürfind
(oder wenn Ihr System dies hat-print0
, können Sie esfind … -print0 | xargs -0 …
stattdessen verwenden; dies ist nur nützlich, um auf mehrere Dateien gleichzeitig zu reagieren, wenn Sie eine Portabilität auf alte Linux-Systeme oder aktuelle OpenBSD-Systeme benötigen, die dies-print0
jedoch nicht tun-exec … {} +
).Beachten Sie, dass Sie doppelte Anführungszeichen vermissen
$f
(diese werden nicht benötigt, wenn dies das Ergebnis der Aufteilung ist und Sie sich seitdem nicht geändert habenIFS
und das Globbing deaktiviert ist. Setzen Sie jedoch immer doppelte Anführungszeichen, es sei denn, Sie wissen, warum Sie dies können. ' t lass sie an).Dies ist umständlich und nicht portierbar (
stat
existiert nicht auf allen Systemen, und seine Argumente unterscheiden sich zwischen den verschiedenen Systemen, auf denen es existiert).touch
hat eine tragbare Option, um eine Datei auf den Zeitstempel einer anderen Datei zu setzen :touch -r REFERENCE_FILE FILE
. Ich würde stattdessen einen von zwei Ansätzen empfehlen:touch -r
auf, um das Datum der neuen Datei festzulegen, und verschieben Sie die neue Datei schließlich an ihren Platz. Es ist besser sicherzustellen, dass die Ausgabe in Ordnung ist, bevor etwas mit der Eingabe passiert. Andernfalls gehen Daten verloren, wenn die Umwandlung aus irgendeinem Grund unterbrochen wird (z. B. aufgrund eines Stromausfalls).touch -r
zweimal verwenden: einmal, um das Datum der Originaldatei in einer leeren temporären Datei zu speichern (die automatisch erstellt wird), und erneut nach der Umwandlung, um das Datum wiederherzustellen Verwenden der temporären Datei.Somit:
quelle
Aus irgendeinem Grund habe ich die Antwort über verpasst
touch -r
; Wenn Sie aus irgendeinem seltsamen Grund weder GNU-Coreutilsstat
wie in der akzeptierten Antwort haben noch verwenden könnentouch -r
,touch
erfahren Sie hier, wie Sie den Zeitstempel in einem freundlichen Format mit einem BSD-ähnlichen Format erhaltenstat
.Aber wirklich, benutze einfach
touch -r
:quelle
Ich hatte das gleiche Problem, als ich aus dem "Filmemachen" kam.
Im folgenden Beispiel
orig_file.wav
befindet sich die Datei mit dem ursprünglichen Zeitstempel, währendprocessed_file.wav
die Datei denselben Inhalt, aber falschen Zeitstempel aufweist.VOR:
localhost $ ls -lh orig_file.wav processed_file.wav Jan 23 17:15 processed_file.wav Jul 9 2018 orig_file.wav
DER BEFEHL:
localhost $ touch -t $(date --date=@`stat -f%B orig_file.wav` +%Y%m%d%H%M.%S) processed_file.wav
NACH:
localhost $ ls -lh orig_file.wav processed_file.wav Jul 9 2018 processed_file.wav Jul 9 2018 orig_file.wav
ANMERKUNGEN:
stat
In invertierten Ticks erhalten Sie den Erstellungszeitstempel der Originaldatei als Unix-Epochenzeit (in Sekunden). Das @ von coreutils konvertiert es in ein ISO-Datum,date
das YYYYMMDDHHmm.SS verstehen und neu formatierentouch
kann, damit es es verstehen kann. Ich habe dendate
Befehl in $ () als Äquivalent zu invertierten Ticks eingefügt, da diese nicht im selben Befehl wiederverwendet werden können.quelle
touch -r
)? (2)stat
kann eingegeben werden$(…)
; Sie können in einem Befehl mehrfach verwendet werden.