using stat pour fournir un horodatage pour le toucher

Je suis en train d'essayer d'OCR certains documents insitu (à partir d'une command line Linux sur un partage Windows). Le process d'OCRing est trouvé et je me suis débrouillé en utilisant la command find pour diriger correctement les files dans la boucle.

Cependant, j'ai besoin de conserver l'horodatage original pour modifié. J'essaye actuellement d'utiliser stat et de 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 command tactile échoue. en exécutant les commands séparément, je remarque que "stat -c" est quelque chose comme ceci:

1334758696

qui est comme aucune date je sais. J'ai l'printing d'être proche mais je ne peux pas find comment convertir la date que j'ai dans une version amicale. Est-ce une forme de secondes de quelque chose?

stat's sortie stat's est un horodatage Unix, également appelé secondes depuis l'époque .

Tous les coreutils GNU qui acceptent une date vous permettent de placer un horodatage en préfixant l'horodatage avec un @ .

Alors essaye ça

 touch -d @$ORIGTS $f 

Voir coreutils – Secondes depuis l'époque

touch peut utiliser l'horodatage d'un file en utilisant l'option -r . Vous voudrez peut-être sortir dans un autre file (je suppose ci-dessous que -if est le file d'input et -of est le file de sortie)

 for f in ...; do sudo /opt/ABBYYOCR9/abbyyocr9 ... -if $f ... -of $f.new touch -r $f $f.new mv $f.new $f done 

IFS=$(echo -en "\n\b")

Puisque vous assumez un shell avec echo -e , et que vous avez quand même bash dans votre ligne de shebang, vous pouvez utiliser IFS=$'\n\b' . Faire revenir en arrière un séparateur est plutôt étrange. Vous n'avez pas besoin d' IFS pour ce que vous faites de toute façon.

OLDIFS=$IFS

IFS=$OLDIFS

Notez que cela restaure l'ancienne valeur de IFS uniquement si IFS était initialement défini. Si IFS n'était pas initialisé, cela définit IFS sur la string vide, ce qui est complètement différent. Dans ksh, bash ou zsh, si vous devez définir temporairement IFS , vous pouvez écrire votre code dans une fonction et rendre IFS local à cette fonction. Dans d'autres coquilles, vous devez faire attention au cas non réglé.

`find /mnt/library/Libra/Libra/Ashfords -name "*.pdf"`

N'utilisez jamais la substitution de command sur la sortie de find .

  • Cela divise la sortie aux caractères dans $IFS . Si vous définissez IFS sur une nouvelle ligne, cela divise la sortie sur les returns à la ligne, mais vous ne pouvez toujours pas gérer les noms de files contenant des returns à la ligne.
  • Non seulement le résultat de la substitution de command est divisé en mots, mais chaque mot est ensuite utilisé comme un motif glob. Si vous avez des files appelés A[12].pdf , A1.pdf et A2.pdf , vous vous refindez avec A1.pdf A2.pdf A1.pdf A2.pdf . Vous pouvez désactiver la suppression de globes avec set -f (et de nouveau avec set +f ), mais ici (comme la plupart du time), la bonne façon est de ne pas utiliser la substitution de commands.

Utilisez l'argument -exec pour find (ou si votre système a -print0 , vous pouvez utiliser find … -print0 | xargs -0 … place, ce n'est utile que pour find … -print0 | xargs -0 … plusieurs files à la fois si vous avez besoin de la portabilité d'anciens systèmes Linux ou systèmes OpenBSD actuels qui ont -print0 mais pas -exec … {} + ).

 ORIGTS=`stat -c "%Y" $f` # [transform $f] touch -t $ORIGTS $f 

Notez que vous manquez des guillemets autour de $f (ils ne sont pas nécessaires si ce sont les résultats de la division et que vous n'avez pas changé d' IFS depuis et que la suppression est désactivée mais placez toujours des guillemets doubles sauf si vous savez pourquoi vous ne pouvez pas les laisser).

C'est maladroit et non portable (la 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 possède une option portable pour définir un file sur l'horodatage d'un autre file: touch -r REFERENCE_FILE FILE . Je reorderais plutôt l'une des deux approches suivantes:

  • Si vous le pouvez, commencez par transformer le file original en un nouveau file, puis appelez touch -r pour définir la date du nouveau file et enfin déplacez le nouveau file en place. Il est préférable de s'assurer que la sortie est correcte avant que quelque chose arrive à l'input; Sinon, si la transformation est interrompue pour une raison quelconque (par exemple une panne de courant), vous perdrez des données.
  • Si la transformation est une boîte noire sur laquelle vous n'avez aucun contrôle, vous pouvez utiliser touch -r deux fois: une fois pour save la date du file original sur un file temporaire vide (qui sera créé automatiquement), puis après la transformation restaurer la date en utilisant le file temporaire.

Ainsi:

 find /mnt/library/Libra/Libra/Ashfords -name '*.pdf' \ -exec sh -c 'transform "$0" to "$0.tmp" && touch -r "$0" "$0.tmp" && mv -f "$0.tmp" "$0"' {} \;