utilizando estadísticas para proporcionar marca de tiempo para el tacto

11

Estoy tratando de OCR algunos documentos in situ (desde una línea de comandos de Linux en un recurso compartido de Windows). El proceso de OCR es buscar y me he confundido con el comando de búsqueda para canalizar los archivos a través del bucle correctamente.

Sin embargo, necesito preservar la marca de tiempo original para modificar. Actualmente estoy tratando de usar stat y tocar como a continuación:

#!/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

Por supuesto, el comando táctil falla. al ejecutar los comandos por separado, noto que "stat -c" es algo similar a esto:

1334758696

lo cual es como ninguna fecha lo sé. Siento que estoy cerca pero no puedo resolver cómo convertir la fecha que tengo en una versión táctil. ¿Es alguna forma de segundos de algo?

Tim Alexander
fuente
Aparte: su uso de IFSparece inusual. ¿Realmente quería dividirse en la tecla de retroceso ( \b)? Consulte unix.stackexchange.com/questions/9496/… para obtener algunos consejos.
Mikel

Respuestas:

17

stat'sLa salida es una marca de tiempo de Unix, también llamada segundos desde la época .

Todos los coreutils de GNU que aceptan una fecha le permiten poner una marca de tiempo en su lugar al prefijar la marca de tiempo con un @.

Así que prueba esto

touch -d @$ORIGTS $f

Ver coreutils - Segundos desde la época

Mikel
fuente
¡Ah, eso explica muchas marcas de tiempo que he visto en Linux ahora! Muchas gracias
Tim Alexander
8

touchpuede usar la marca de tiempo de un archivo usando la -ropción Es posible que desee enviar a un archivo diferente (supongo a continuación que -ifes un archivo de entrada y -ofun archivo de salida)

for f in ...; do
    sudo /opt/ABBYYOCR9/abbyyocr9 ... -if $f ... -of $f.new
    touch -r $f $f.new
    mv $f.new $f
done
Glenn Jackman
fuente
+1 por evitar stat.
l0b0
3

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

Ya que está asumiendo una concha echo -ey tiene un golpe en su línea shebang de todos modos, puede usar IFS=$'\n\b'. Hacer que el retroceso sea un separador es bastante extraño. No necesitas IFSlo que estás haciendo de todos modos.

OLDIFS=$IFS
...
IFS=$OLDIFS

Tenga en cuenta que esto restaura el valor anterior de IFSsolo si IFSse estableció inicialmente. Si IFSinicialmente no se configuró, esto se establece IFSen la cadena vacía, que es completamente diferente. En ksh, bash o zsh, si necesita configurarlo IFStemporalmente, puede escribir su código en una función y convertirlo en IFSlocal. En otros proyectiles, debe tener cuidado con el caso sin configurar.

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

Nunca use la sustitución de comandos en la salida de find.

  • Esto divide la salida en los caracteres en $IFS. Si establece IFSuna nueva línea, esto divide la salida en nuevas líneas, pero aún no puede manejar los nombres de archivo que contienen nuevas líneas.
  • El resultado de la sustitución de comandos no solo se divide en palabras, sino que cada palabra se usa como un patrón global. Si llama a los archivos A[12].pdf, A1.pdfy A2.pdfterminará con A1.pdf A2.pdf A1.pdf A2.pdf. Puede desactivar el globbing con set -f(y volver a activarlo con set +f), pero aquí (como la mayoría de las veces) la forma correcta es no usar la sustitución de comandos.

Use el -execargumento para find(o si su sistema lo tiene -print0, puede usarlo find … -print0 | xargs -0 …en su lugar; esto solo es útil para actuar en múltiples archivos a la vez si necesita portabilidad a sistemas Linux antiguos o sistemas OpenBSD actuales que tienen -print0pero no -exec … {} +).

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

Tenga en cuenta que le faltan comillas dobles $f(no son necesarias si estos son los resultados de la división y no ha cambiado IFSdesde entonces y el globbing está desactivado, pero realmente, siempre ponga comillas dobles a menos que sepa por qué puede ' no los dejes puestos).

Esto es torpe y no portátil ( statno existe en todos los sistemas, y sus argumentos son diferentes en los diferentes sistemas donde existe). touchtiene una opción portátil para configurar un archivo a la marca de tiempo de otro archivo: touch -r REFERENCE_FILE FILE. En su lugar, recomendaría uno de dos enfoques:

  • Si puede, primero transforme el archivo original en un nuevo archivo, luego llame touch -rpara establecer la fecha del nuevo archivo y finalmente mueva el nuevo archivo a su lugar. Es mejor asegurarse de que la salida esté bien antes de que algo le pase a la entrada; de lo contrario, si la transformación se interrumpe por algún motivo (por ejemplo, una falla de energía), perderá datos.
  • Si la transformación es un cuadro negro sobre el que no tiene control, puede usar touch -rdos veces: una para guardar la fecha del archivo original en un archivo temporal vacío (que se creará automáticamente), luego otra vez después de la transformación para restaurar la fecha usando el archivo temporal.

Así:

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"' {} \;
Gilles 'SO- deja de ser malvado'
fuente
0

Por alguna razón me perdí la respuesta touch -r; si, por alguna extraña razón, no tiene GNU coreutils ' statcomo en la respuesta aceptada ni puede usar touch -r, aquí le touchmostramos cómo obtener la marca de tiempo en formato amigable con un formato BSD stat.

% /usr/bin/stat -f '%Sm' johnson                   
Oct 23 22:51:00 2012
% /usr/bin/stat -t '%Y%m%d%H%M.%S' -f '%Sm' johnson
201210232251.00
% touch foo
% touch -t $(/usr/bin/stat -t '%Y%m%d%H%M.%S' -f '%Sm' johnson) foo
% /usr/bin/stat -f '%Sm' foo                    
Oct 23 22:51:00 2012

Pero realmente, solo usa touch -r:

% touch foo
% touch -r johnson foo
% /usr/bin/stat -f '%Sm' foo
Oct 23 22:51:00 2012
Nicholas Riley
fuente
0

Tuve el mismo problema, viniendo del proceso de 'hacer películas'.

En el ejemplo a continuación se orig_file.wavmuestra el archivo con la marca de tiempo original, mientras que processed_file.waves el archivo con el mismo contenido, pero con la marca de tiempo incorrecta.

ANTES DE:

localhost $ ls -lh orig_file.wav processed_file.wav Jan 23 17:15 processed_file.wav Jul 9 2018 orig_file.wav

EL COMANDO:

localhost $ touch -t $(date --date=@`stat -f%B orig_file.wav` +%Y%m%d%H%M.%S) processed_file.wav

DESPUÉS:

localhost $ ls -lh orig_file.wav processed_file.wav Jul 9 2018 processed_file.wav Jul 9 2018 orig_file.wav

NOTAS

staten tics invertidos le da la marca de tiempo de creación del archivo original como tiempo de época de Unix (en segundos). El @ from coreutils lo convierte en una fecha iso que datepuede entender y formatear con AAAAMMDDHHmm.SS para que touchpueda entenderlo. Puse el datecomando en $ (), como un equivalente de tics invertidos, ya que no se pueden reutilizar en el mismo comando.

dominikz
fuente
(1) Esto parece ser casi exactamente lo mismo que la respuesta de Nicholas Riley, pero más complicado. ¿Por qué alguien querría usar esto en lugar de eso (o, mejor aún, la respuesta de Glenn Jackman , usando touch -r)? (2)  stat se puede poner $(…); se pueden usar varias veces en un solo comando.
G-Man dice 'reinstalar a Monica' el
Aparte de su respuesta usando el tiempo de modificación en lugar de crear tiempo, parece que estás en lo correcto. No noté esta otra respuesta. Puedes votar por el mío.
dominikz
Bueno, si me lo pides, no es divertido. :-) ⁠
G-Man dice 'reinstalar a Mónica' el