J'essaie d'OCR certains documents in situ (à partir d'une ligne de commande Linux sur un partage Windows). Le processus d'OCRing est find et je me suis trompé en utilisant la commande find pour diriger correctement les fichiers dans la boucle.
Cependant, je dois conserver l'horodatage d'origine pour les modifications. J'essaie actuellement d'utiliser stat et toucher comme ci-dessous:
#!/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
Bien sûr, la commande tactile échoue. en exécutant les commandes séparément, je remarque que "stat -c" est quelque chose du genre:
1334758696
qui ne ressemble à aucune date que je connaisse. J'ai l'impression d'être proche, mais je n'arrive pas à savoir comment convertir la date que j'ai en une version tactile. Est-ce une forme de secondes de quelque chose?
IFS
semble inhabituelle. Vouliez-vous vraiment vous séparer sur backspace (\b
)? Voir unix.stackexchange.com/questions/9496/… pour quelques conseils.Réponses:
stat's
La sortie est un horodatage Unix, également appelé secondes depuis l'époque .Tous les coreutils GNU qui acceptent une date vous permettent de mettre un horodatage à la place en préfixant l'horodatage avec un
@
.Alors essayez ceci
Voir coreutils - Secondes depuis l'époque
la source
touch
peut utiliser l'horodatage d'un fichier en utilisant l'-r
option. Vous voudrez peut-être sortir dans un fichier différent (je suppose que ci-dessous c'est le-if
fichier d'entrée et le-of
fichier de sortie)la source
stat
.Puisque vous supposez un shell avec
echo -e
, et que vous avez quand même bash dans votre ligne de shebang, vous pouvez utiliserIFS=$'\n\b'
. Faire du retour arrière un séparateur est plutôt bizarre. De toute façon, vous n'avez pas besoinIFS
de ce que vous faites.Notez que cela restaure l'ancienne valeur de
IFS
uniquement si elle aIFS
été initialement définie. SiIFS
était initialement non défini, cela définitIFS
la chaîne vide, ce qui est complètement différent. En ksh, bash ou zsh, si vous avez besoin de définirIFS
temporairement, vous pouvez écrire votre code dans une fonction et rendreIFS
local cette fonction. Dans d'autres coquilles, vous devez faire attention au cas non réglé.N'utilisez jamais de substitution de commande sur la sortie de
find
.$IFS
. Si vous définissezIFS
une nouvelle ligne, cela divise la sortie aux nouvelles lignes, mais vous ne pouvez toujours pas gérer les noms de fichiers contenant des nouvelles lignes.A[12].pdf
,A1.pdf
etA2.pdf
, vous vous retrouverez avecA1.pdf A2.pdf A1.pdf A2.pdf
. Vous pouvez désactiver la globalisation avecset -f
(et la réactiver avecset +f
), mais ici (comme la plupart du temps) la bonne façon n'est pas d'utiliser la substitution de commandes.Utilisez l'
-exec
argument pourfind
(ou si votre système a-print0
, vous pouvez utiliser à lafind … -print0 | xargs -0 …
place; cela n'est utile que pour agir sur plusieurs fichiers à la fois si vous avez besoin de portabilité vers les anciens systèmes Linux ou les systèmes OpenBSD actuels qui en ont-print0
mais pas-exec … {} +
).Notez que vous manquez des guillemets doubles
$f
(ils ne sont pas nécessaires si ce sont les résultats du fractionnement et que vous n'avez pas changéIFS
depuis et que la globalisation est désactivée, mais vraiment, mettez toujours des guillemets doubles sauf si vous savez pourquoi vous pouvez '' ne les laissez pas allumés).Ceci est maladroit et non portable (
stat
n'existe pas sur tous les systèmes, et ses arguments sont différents selon les différents systèmes où il existe).touch
a une option portable pour définir un fichier à l'horodatage d'un autre fichier:touch -r REFERENCE_FILE FILE
. Je recommanderais plutôt l'une des deux approches:touch -r
pour définir la date du nouveau fichier, et enfin déplacez le nouveau fichier en place. Il est préférable de s'assurer que la sortie est correcte avant que quoi que ce soit arrive à l'entrée; sinon, si la transformation est interrompue pour une raison quelconque (par exemple une panne de courant), vous perdrez des données.touch -r
deux fois: une fois pour enregistrer la date du fichier d'origine sur un fichier temporaire vide (qui sera automatiquement créé), puis à nouveau après la transformation pour restaurer la date en utilisant le fichier temporaire.Donc:
la source
Pour une raison quelconque, j'ai raté la réponse
touch -r
; si, pour une raison étrange, vous n'avez pas de coreutils GNUstat
comme dans la réponse acceptée et que vous ne pouvez pas utilisertouch -r
, voici comment obtenir l'horodatage autouch
format convivial avec un BSD-likestat
.Mais vraiment, utilisez simplement
touch -r
:la source
J'ai eu le même problème, venant du processus de "réalisation de films".
Dans l'exemple ci
orig_file.wav
- dessous se trouve le fichier avec l'horodatage d'origine, tandis queprocessed_file.wav
le fichier avec le même contenu, mais un horodatage incorrect.AVANT:
localhost $ ls -lh orig_file.wav processed_file.wav Jan 23 17:15 processed_file.wav Jul 9 2018 orig_file.wav
LA COMMANDE:
localhost $ touch -t $(date --date=@`stat -f%B orig_file.wav` +%Y%m%d%H%M.%S) processed_file.wav
APRÈS:
localhost $ ls -lh orig_file.wav processed_file.wav Jul 9 2018 processed_file.wav Jul 9 2018 orig_file.wav
REMARQUES:
stat
en ticks inversés vous donne l'horodatage de création du fichier d'origine en temps d'époque unix (en secondes). Le @ de coreutils le convertit en une date iso quidate
peut comprendre et reformater avec YYYYMMDDHHmm.SS afin detouch
pouvoir le comprendre. J'ai mis ladate
commande dans $ (), comme un équivalent de ticks inversés, car ils ne peuvent pas être réutilisés dans la même commande.la source
touch -r
)? (2)stat
peut être installé$(…)
; ils peuvent être utilisés plusieurs fois dans une seule commande.