Windows 공유의 Linux 명령줄에서 일부 문서를 그 자리에서 OCR하려고 합니다. OCRing 프로세스는 find이며 루프를 통해 파일을 적절하게 파이프하기 위해 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
날짜를 전혀 모르는 것 같습니다. 가까워진 것 같은 느낌이 들지만 내 날짜를 터치하기 쉬운 버전으로 변환하는 방법을 알 수 없습니다. 초 단위인가요?
답변1
stat's
출력은 Unix 타임스탬프입니다.에포크 이후 초.
날짜를 허용하는 모든 GNU coreutils에서는 타임스탬프 앞에 @
.
그러니 이것을 시도해 보세요
touch -d @$ORIGTS $f
답변2
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
답변3
IFS=$(echo -en "\n\b")
를 사용하여 쉘을 가정 echo -e
하고 어쨌든 Shebang 라인에 bash가 있으므로 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
사용할 수 있습니다. 이는 고대 Linux 시스템 또는 find … -print0 | xargs -0 …
현재는 있지만 OpenBSD 시스템 으로 포팅해야 하는 경우 한 번에 여러 파일을 작업하는 데만 적합합니다. ).-print0
-exec … {} +
ORIGTS=`stat -c "%Y" $f` # [transform $f] touch -t $ORIGTS $f
큰따옴표가 누락되었습니다(분할의 결과이고 그 이후로 변경하지 않았고 와일드카드를 끈 경우에는 $f
필요하지 않지만 실제로는 사용자가 알지 않는 한 큰따옴표가 항상 추가됩니다). 왜 ' IFS
열어두지 마세요).
이는 다루기 힘들고 이식성이 없습니다( 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"' {} \;
답변4
"영화 제작" 과정에서도 같은 문제가 있었습니다.
아래 예는 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
invertedticks에서는 원본 파일의 생성 타임스탬프를 Unix Epoch 시간(초)으로 제공합니다. coreutils의 @는 이를 date
이해할 수 있는 iso 날짜로 변환하고 YYYYMMDDHHmm.SS를 사용하여 touch
이해할 수 있도록 형식을 다시 지정합니다. date
동일한 명령에서 재사용할 수 없기 때문에 역방향 틱과 동일한 $()에 명령을 넣었습니다 .