쉘 스크립트를 사용하여 고유한 파일 이름 형식과 가장 최근 생성 날짜를 가진 특정 PDF를 선택하시겠습니까?

쉘 스크립트를 사용하여 고유한 파일 이름 형식과 가장 최근 생성 날짜를 가진 특정 PDF를 선택하시겠습니까?

스크립팅에 도움이 필요합니다. 현재 파일 이름에 대한 특정 요구 사항을 충족하는 PDF 파일을 선택하여 다른 위치로 이동하려고 합니다.

제가 선택하려는 파일 이름 형식에는 아래 예와 같이 별도의 섹션이 있습니다.

I_XXX_PACK_6788669_6_9358869.pdf

내가 원하는 것은 파일 이름의 마지막 부분(예 9358869: )이 있는 파일만 선택하고 디렉토리의 다른 모든 pdf 파일을 무시하는 것입니다.

Unix 도구(POSIX find, sed, grep 등)를 사용하여 수행할 수 있습니까? 이제 내 주요 문제는 파일 이름에서 6개의 구분된 부분으로 구성된 하나의 파일만 가져오고 다른 모든 파일은 무시하려고 하는 것입니다.

  • 그리고 시스템 시간 1시간 전에 생성된 파일만 선택할 수 있나요? 시간을 확인하기 위해 다른 파일 형식에서는 sed를 사용했지만 pdf 파일에서는 사용하지 않았습니다. 그래서 이것이 가능한지 잘 모르겠습니다

답변1

와 같은 파일이 있고 6개의 구분된 섹션과 일치하는 파일 I_XXX_PACK_6788669_6_9358869.pdf만 필요하며 _그 중 마지막 섹션은 9358869.

이는 다음으로 끝나는( 0개 이상의 문자와 일치하는 와일드카드 ) 로 구분된 최소 6개 _부분 과 일치합니다 .*_9358869.pdf

*_*_*_*_*_9358869.pdf

다음을 사용하여 지난 한 시간 동안 수정되었지만 생성되지 않은 파일을 찾을 수 있습니다 find.

find /path/to/directory -type f -mmin -60

POSIX를 허용하기 위해서는 적절한 age를 사용 -newer {file}하고 설정 해야 합니다. {file}POSIX는 파일의 수정된 날짜 시간을 과거 1시간으로 설정하는 안정적인 방법을 제공하지 않지만 표시한 대로우리는 그것을 사용할 수 있습니다:

printf -v curr '%(%s)T'
past=$(printf '%(%Y%m%d%H%M)T\n' "$((curr - 60*60))")
touch -t "$past" /path/to/timestamp

find /path/to/directory -type f -newer /path/to/timestamp

마지막으로 두 가지를 병합합니다.

touch -t "$(printf -v curr '%(%s)T'; printf '%(%Y%m%d%H%M)T\n' "$((curr - 60*60))")" /path/to/timestamp
find /path/to/directory -type f -newer /path/to/timestamp -name '*_*_*_*_*_9358869.pdf'

답변2

find . -name '[!_]*_*_*_*_*_*[!_].pdf' ! -name '*_*_*_*_*_*_*' ! -name '*__*'

.pdf이름이 5~5자로 끝나고 루트 이름의 __-구분된 부분이 비어 있지 않은 파일(모든 유형)이 보고됩니다.

일부 find구현의 경우 현재 로케일에서 이름을 텍스트로 디코딩할 수 없는 파일도 제외됩니다.

Chris가 말했듯이 지난 시간에 수정된 내용을 제한하기 위해 일부 구현에서는 이를 지원 -newermt '1 hour ago'하거나 표준 -mmin 60-mtime -1m아니며 find그 외에는 POSIX와 동등한 것이 없습니다 -newer some-file-with-a-last-modification-time-one-hour-ago.

POSIX 방식으로 검색 참조 시간을 생성하는 일반적인 방법은 다음과 같습니다.

TZ=XXX0 touch -t "$(TZ=XXX1 date +%Y%m%d%H%M.%S)" some-file-with-a-last-modification-time-one-hour-ago

여기서 는 시간대(시간대라고 명명했지만 여기서는 이름은 관련이 없음)에서 호출 date되며 UTC보다 1시간 늦도록 정의하고 결과 타임스탬프를 UTC 시간(시간대라고도 하지만 UTC 0시간 후(UTC)보다 오래되었으므로 결국 1시간 된 파일을 생성하게 됩니다.XXXtouchdateXXX

그 후에는 다음을 수행할 수 있습니다.

find . -name '[!_]*_*_*_*_*_*[!_].pdf' \
       ! -name '*_*_*_*_*_*_*' \
       ! -name '*__*' \
       -newer some-file-with-a-last-modification-time-one-hour-ago

당신과 같다면태그는 POSIX 구문 사용에만 국한되지 않고 외부 유틸리티 없이 모든 작업을 수행할 수 있는 곳에서 sh사용할 수 있음을 나타냅니다.zsh

set -o extendedglob
print -rC1 -- **/([^_]##_)(#c5)_[^_]##.pdf(ND-.mh-1)

어디:

  • **/모든 수준의 하위 디렉터리와 일치(0 포함)
  • [^_]다음을 제외한 모든 문자와 일치합니다._
  • x##와 동일하게 하나 이상의 xes와 일치합니다 x(#c1,).
  • x(#c5)정확히 5 xes와 일치합니다.
  • N일치하는 항목이 없으면 ullglob은 오류를 보고하는 대신 비어 있는 상태로 확장됩니다.
  • Dotglob에는 숨겨진 내용이 포함되어 있습니다.
  • .mh-1일반 파일은 마지막으로 수정된 지 1시간 미만(또는 향후)이며 -심볼릭 링크 확인 후 검사가 수행됩니다.
  • print -rC1 -- print논쟁은 raw와 olumn에 있습니다 1 C.

마지막 3개 부분이 10진수 정수여야 하는 파일로 일치를 제한하려면 다음과 같이 변경할 수 있습니다.

set -o extendedglob
print -rC1 -- **/([^_]##_)(#c3)<->_<->_<->.pdf(ND-.mh-1)

숫자 일치 연산자의 형식은 어디에 <->있지만 <1-20>여기에는 경계가 없으므로 모든 10진수 정수가 일치합니다(하나 이상의 ASCII 10진수 시퀀스를 작성할 수도 있습니다 [0-9]##).


¹ -type f유형만 고려한 파일을 추가할 수 있습니다.정기적인(fifo, 장치, 디렉터리, 파이프와는 반대로...) 그러나 일반 파일에 대한 심볼릭 링크도 제외된다는 점에 유의하세요. 이를 포함하려면 가 필요 -xtype f하지만 이는 비표준(GNU) 확장이기도 합니다.

관련 정보