використовуючи stat для надання часової позначки для дотику


11

Я намагаюся OCR деякими документами insitu (з командного рядка linux на Windows share). Процес 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

Звичайно сенсорна команда не вдається. запускаючи команди окремо, я помічаю, що "stat -c" - це щось по лінії цього:

1334758696

що не знає жодної дати, яку я не знаю. Я відчуваю себе так, ніби я близький, але не можу розробити, як перетворити дату, яку я маю, у зручну для дотику версію. Це якась форма секунд від чогось?


Убік: ваше використання IFSздається незвичним. Ви дійсно хотіли розділити на backspace ( \b)? Дивіться unix.stackexchange.com/questions/9496/… для деяких порад.
Мікель

Відповіді:


17

stat'sВихід - часова мітка Unix, яка також називається секундами з епохи .

Усі основні програми GNU, які приймають дату, дозволяють замість цього поставити часову позначку, префіксуючи позначку часу @.

Тож спробуйте це

touch -d @$ORIGTS $f

Побачити основні елементи - секунди з епохи


ах, що пояснює багато часових позначок, які я бачив у Linux зараз! Дякую багато
Тім Олександр

8

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

+1 для уникнення stat.
l0b0

3

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

Оскільки ви припускаєте снаряд echo -e, і у вас все-таки вибух у вашій лінії шебанг, ви можете використовувати IFS=$'\n\b'. Зробити роздільну частину заднього простору досить дивно. Вам все одно не потрібно 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новий рядок, то це розбиває вихід на нові рядки, але ви все одно не можете обробити імена файлів, що містять нові рядки.
  • Не тільки результат заміни команд розбивається на слова, але потім кожне слово використовується як глобальний зразок. Якщо ви зателефонували до файлів 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і глобус вимкнено, але насправді завжди ставити подвійні лапки, якщо ви не знаєте, чому ви можете " t залиште їх увімкнено).

Це незграбно і не портативно ( 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"' {} \;

0

Я чомусь пропустив відповідь про touch -r; якщо з якихось дивних причин ви не маєте GNU coreutils ', statяк у прийнятій відповіді, і не можете використовувати touch -r, ось як отримати позначку часу у touch-дружньому форматі з 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

Але дійсно, просто використовуйте touch -r:

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

0

У мене була така ж проблема, що виникла в процесі "проходження фільму".

У наведеному нижче прикладі orig_file.wav- файл із оригінальною міткою часу, тоді processed_file.wavяк файл із тим самим вмістом, але неправильною позначкою часу.

ПЕРЕД:

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

КОМАНДА:

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

ПІСЛЯ:

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

ПРИМІТКИ:

statза допомогою перевернутих галочок дає змогу створювати часову позначку вихідного файлу як unix epoch time (у секундах). @ Від coreutils перетворює його на дату iso, яка dateможе зрозуміти та переформатувати за допомогою YYYYMMDDHHmm.SS, щоб вона touchмогла зрозуміти це. Я ставлю dateкоманду в $ (), як еквівалент перевернутих тиків, оскільки вони не можуть бути використані повторно в одній команді.


(1) Це здається майже таким же, як відповідь Ніколаса Райлі, але складніше. Чому б хто - небудь хоче використовувати це замість того , що (або, ще краще, відповідь Glenn Джекмана , використовуючи touch -r)? (2)  stat можна поставити $(…); їх можна використовувати кілька разів в одній команді.
G-Man каже: "Відновіть Моніку"

Окрім його відповіді, що використовує час модифікації, а не створює час, ви, здається, правильні. Я не помітив цієї іншої відповіді. Ви можете проголосувати мою.
dominikz

Ну, якщо ви попросите мене, це не весело. :-) ⁠
G-Man каже: "Відновити Моніку"
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.