stat를 사용하여 터치 타임스탬프 제공

stat를 사용하여 터치 타임스탬프 제공

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

바라보다coreutils - 에포크 이후 초

답변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설정됩니다 . IFSksh, bash 또는 zsh에서 임시 설정이 필요한 경우 IFS함수에 코드를 작성하고 IFS해당 함수에 고유하게 만들 수 있습니다. 다른 쉘에서는 설정되지 않은 조건에 주의해야 합니다.

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

의 출력에 명령 대체를 사용하지 마십시오 find.

  • 이렇게 하면 출력이 의 문자로 분할됩니다 $IFS. 개행으로 설정하면 IFS출력이 개행으로 분할되지만 여전히 개행이 포함된 파일 이름을 처리할 수 없습니다.
  • 명령 대체의 결과는 단어로 분할될 뿐만 아니라 각 단어가 전역 패턴으로 사용됩니다. 파일 이름이 A[12].pdf, A1.pdfA2.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

노트:

statinvertedticks에서는 원본 파일의 생성 타임스탬프를 Unix Epoch 시간(초)으로 제공합니다. coreutils의 @는 이를 date이해할 수 있는 iso 날짜로 변환하고 YYYYMMDDHHmm.SS를 사용하여 touch이해할 수 있도록 형식을 다시 지정합니다. date동일한 명령에서 재사용할 수 없기 때문에 역방향 틱과 동일한 $()에 명령을 넣었습니다 .

관련 정보