Próbuję OCR niektóre dokumenty insitu (z wiersza polecenia systemu Linux na współużytkowaniu systemu Windows). Proces OCRing znajduje się w find, a ja mętlikami użyłem polecenia find, aby poprawnie poprowadzić pliki przez pętlę.
Jednak muszę zachować oryginalny znacznik czasu dla zmodyfikowanego. Obecnie próbuję użyć statystyk i dotknąć, jak poniżej:
#!/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
Oczywiście polecenie dotykowe kończy się niepowodzeniem. osobne uruchamianie poleceń Zauważyłem, że „stat -c” to coś takiego:
1334758696
który jest jak żadna randka, którą znam. Czuję się, jakbym był blisko, ale nie mogę wymyślić, jak przekonwertować datę, którą mam, na wersję przyjazną dla dotyku. Czy to jakaś sekunda z czegoś?
IFS
wydaje się niezwykłe. Czy naprawdę chciałeś podzielić na backspace (\b
)? Zobacz wskazówki na unix.stackexchange.com/questions/9496/ ...Odpowiedzi:
stat's
wyjście to uniksowy znacznik czasu, zwany także sekundami od epoki .Wszystkie jądra GNU, które akceptują datę, pozwalają zamiast tego wstawić znacznik czasu, poprzedzając go znacznikiem czasu
@
.Więc spróbuj tego
Zobacz coreutils - Sekundy od epoki
źródło
touch
może użyć znacznika czasu pliku za pomocą-r
opcji. Możesz chcieć wyprowadzić plik do innego pliku (zakładam, że poniżej-if
jest plik wejściowy i-of
plik wyjściowy)źródło
stat
.Ponieważ zakładasz powłokę
echo -e
, a i tak masz uderzenie w linii shebang, możesz użyćIFS=$'\n\b'
. Przekształcanie separatora w backspace jest raczej dziwne. I tak nie potrzebujeszIFS
tego, co robisz.Zauważ, że przywraca to starą wartość
IFS
tylko wtedy, gdyIFS
została początkowo ustawiona. JeśliIFS
początkowo był rozbrojony, ustawiaIFS
się na pusty ciąg, który jest zupełnie inny. W ksh, bash lub zsh, jeśli musisz ustawićIFS
tymczasowo, możesz napisać kod w funkcji i ustawić jąIFS
lokalnie. W innych powłokach musisz uważać na nierozbieralną obudowę.Nigdy nie używaj podstawiania poleceń na wyjściu
find
.$IFS
. Jeśli ustawiszIFS
na nową linię, spowoduje to podział wyniku na nowe linie, ale nadal nie możesz obsługiwać nazw plików zawierających nowe linie.A[12].pdf
,A1.pdf
aA2.pdf
skończysz naA1.pdf A2.pdf A1.pdf A2.pdf
. Możesz wyłączyć globowanie za pomocąset -f
(i ponownie za pomocąset +f
), ale tutaj (jak przez większość czasu) właściwym sposobem nie jest stosowanie zastępowania poleceń.Użyj
-exec
argumentu, abyfind
(lub jeśli twój system ma-print0
, możesz użyćfind … -print0 | xargs -0 …
zamiast tego; jest to przydatne tylko do działania na wielu plikach na raz, jeśli potrzebujesz przenośności do starożytnych systemów Linux lub obecnych systemów OpenBSD, które mają,-print0
ale nie-exec … {} +
).Pamiętaj, że brakuje ci podwójnych cudzysłowów
$f
(nie są one potrzebne, jeśli są to wyniki podziału i od tego czasu nie zmieniłeś się,IFS
a globowanie jest wyłączone, ale tak naprawdę zawsze umieszczaj podwójne cudzysłowy, chyba że wiesz, dlaczego możesz „ zostaw je włączone).Jest to niezdarne i nieprzenośne (
stat
nie istnieje we wszystkich systemach, a jego argumenty są różne w różnych systemach, w których istnieje).touch
posiada przenośny opcję, aby ustawić pliku do znacznika czasu innego pliku:touch -r REFERENCE_FILE FILE
. Zamiast tego poleciłbym jedno z dwóch podejść:touch -r
aby ustawić datę nowego pliku, a na koniec przenieś nowy plik na miejsce. Lepiej jest upewnić się, że wyjście jest w porządku, zanim cokolwiek stanie się z danymi wejściowymi; w przeciwnym razie, jeśli transformacja zostanie przerwana z jakiegokolwiek powodu (np. awaria zasilania), utracisz dane.touch -r
dwukrotnie: raz, aby zapisać datę oryginalnego pliku w pustym pliku tymczasowym (który zostanie utworzony automatycznie), a następnie ponownie po transformacji, aby przywrócić datę za pomocą pliku tymczasowego.A zatem:
źródło
Z jakiegoś powodu przegapiłem odpowiedź na temat
touch -r
; jeśli z jakiegoś dziwnego powodu nie masz GNU coreutils 'stat
jak w zaakceptowanej odpowiedzi ani nie możesz użyćtouch -r
, oto jak uzyskać znacznik czasu wtouch
formacie przyjaznym dla BSDstat
.Ale tak naprawdę po prostu użyj
touch -r
:źródło
Miałem ten sam problem, pochodzący z procesu tworzenia filmów.
W poniższym przykładzie
orig_file.wav
jest plik z oryginalnym znacznikiem czasu, podczasprocessed_file.wav
gdy plik o tej samej zawartości, ale niepoprawnym znaczniku czasu.PRZED:
localhost $ ls -lh orig_file.wav processed_file.wav Jan 23 17:15 processed_file.wav Jul 9 2018 orig_file.wav
KOMENDA:
localhost $ touch -t $(date --date=@`stat -f%B orig_file.wav` +%Y%m%d%H%M.%S) processed_file.wav
PO:
localhost $ ls -lh orig_file.wav processed_file.wav Jul 9 2018 processed_file.wav Jul 9 2018 orig_file.wav
UWAGI:
stat
w odwróconych paskach daje znacznik czasu utworzenia oryginalnego pliku jako czas epoki uniksowej (w sekundach). @ Z coreutils konwertuje go na datę ISO, któradate
może zrozumieć i sformatować za pomocą YYYYMMDDHHmm.SS, aby totouch
zrozumieć. Umieszczamdate
polecenie w $ (), jako odpowiednik odwróconych tyknięć, ponieważ nie można ich ponownie użyć w tym samym poleceniu.źródło
touch -r
)? (2)stat
można umieścić$(…)
; można ich używać wiele razy w jednym poleceniu.