используя stat, чтобы обеспечить метку времени для касания

Я пытаюсь выполнить OCR некоторые документы insitu (из командной строки linux на общем ресурсе Windows). Процесс OCRing находит, и я запутался с помощью команды find, чтобы правильно передать файлы через цикл.

Однако мне нужно сохранить исходную временную метку для изменения. В настоящее время я пытаюсь использовать stat и touch, как показано ниже:

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

Конечно, команда touch не работает. запуская команды отдельно, я замечаю, что «stat -c» – это что-то вроде этого:

1334758696

который не похож на дату, которую я знаю. Мне кажется, что я близок, но не могу понять, как преобразовать дату, в которую я имею дело, в удобную для пользователя версию. Это какая-то часть секунд от чего-то?

stat's – это временная метка Unix, также называемая секундами с момента Epoch .

Все GNU coreutils, которые принимают дату, позволяют помещать временную метку вместо префикса метки времени с помощью @ .

Попробуйте это

 touch -d @$ORIGTS $f 

См. Coreutils – Секунды с эпохи

touch может использовать временную метку файла, используя параметр -r . Возможно, вы захотите вывести на другой файл (я предполагаю ниже, что – -if входной файл и -of – выходной файл)

 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")

Поскольку вы предполагаете оболочку с echo -e , и вы все равно используете bash в своей строке shebang, вы можете использовать IFS=$'\n\b' . Создание backspace разделителя довольно странно. Вы не нуждаетесь в IFS для того, что вы делаете в любом случае.

OLDIFS=$IFS

IFS=$OLDIFS

Обратите внимание, что это восстанавливает старое значение IFS только в том случае, если IFS был первоначально установлен. Если IFS был первоначально отключен, это устанавливает IFS в пустую строку, которая совершенно иная. В ksh, bash или zsh, если вам нужно временно установить IFS , вы можете написать свой код в функции и сделать IFS локальной для этой функции. В других оболочках вы должны быть осторожны с неподтвержденным случаем.

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

Никогда не используйте подстановку команд на выходе find .

  • Это разделяет вывод на символы в $IFS . Если вы установите IFS в новую строку, тогда это разделяет вывод на новых строках, но вы по-прежнему не можете обрабатывать имена файлов, содержащие новые строки.
  • Мало того, что результат замены команды разделен на слова, но затем каждое слово используется как шаблон глобуса. Если вы A1.pdf файлы A[12].pdf , A1.pdf и A2.pdf , вы получите A1.pdf A2.pdf A1.pdf A2.pdf . Вы можете отключить с помощью set -f (и обратно с помощью set +f ), но здесь (как и в большинстве случаев) правильным способом является не использование подстановки команд.

Используйте аргумент -exec для find (или если ваша система имеет -print0 , вы можете использовать find … -print0 | xargs -0 … вместо этого, это полезно только для нескольких файлов сразу, если вам нужна переносимость для старых систем Linux или текущие системы OpenBSD, которые имеют -print0 но не -exec … {} + ).

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

Обратите внимание, что вам не хватает двойных кавычек вокруг $f (они не нужны, если они являются результатом разделения, и с тех пор вы не изменили IFS а globbing отключен, но на самом деле всегда ставьте двойные кавычки, если вы не знаете, почему вы не можете их оставить).

Это неудобно и не переносится ( stat не существует во всех системах, и его аргументы различны в разных системах, где он существует). touch имеет переносную опцию для установки файла на метку времени другого файла: touch -r REFERENCE_FILE FILE . Вместо этого я бы порекомендовал один из двух подходов:

  • Если вы можете, сначала преобразуйте исходный файл в новый файл, затем вызовите touch -r чтобы установить дату нового файла, и, наконец, переместите новый файл на место. Лучше убедиться, что выход прекрасен, прежде чем что-либо произойдет с входом; в противном случае, если преобразование прервано по какой-либо причине (например, сбой питания), вы потеряете данные.
  • Если преобразование является черным ящиком, в котором вы не контролируете, вы можете использовать touch -r дважды: один раз, чтобы сохранить дату исходного файла в пустом временном файле (который будет автоматически создан), затем снова после преобразования в восстановите дату, используя временный файл.

Таким образом:

 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"' {} \;