50개의 폴더와 하위 폴더에 많은 수의 이미지 파일(약 100,000개)이 저장되어 있으며 이 데이터를 자동으로 처리하기 위한 스크립트를 작성해야 합니다.
나는 글을 쓰려고 노력 중이야쉘 스크립트다소 복잡한 작업의 경우 현재 올바른 방식으로 실행되도록 노력 중입니다. 따라서 가능한 한 최선의 설명을 제공하기 위해 이 스크립트로 달성하고 싶은 주요 사항을 다음과 같이 적어 보겠습니다.
첫째: 스크립트는 폴더와 하위 폴더를 반복하고 파일 이름과 전체 경로를 추출해야 합니다.
둘째: 파일 이름에는 시간과 날짜 정보가 포함되어 있습니다. 즉, 20180612074405680입니다. 변환하려면 스크립트가 필요합니다.세계시 형식.ie: 2018-06-12 T 07:44:05 TZ +01:00
마지막으로 이 모든 내용을 .csv 파일로 내보내야 합니다.
최종 .csv 파일에는 다음 정보가 포함되어야 합니다.
File path, filename, time
C:/folder/sub-folder/file, 20180612074405680_ZTRDEFO_Blackgen.jpg, Time in UTC
파일 이름의 타임스탬프 형식은 위와 같이 지정되어야 합니다!
명령 을 사용하여 폴더와 하위 폴더를 반복하고 파일 이름을 얻으려고 했지만 find
여전히 파일의 전체 경로를 얻을 수 없습니다.
누구든지 도움을 주거나 팁을 줄 수 있습니까?
답변1
빠르고 더러운:
find "/full/path/of/the/base/dir" -type f -printf "%f;%h;%f\n" \
| sed -r 's/;([0-9][0-9][0-9][0-9])([0-9][0-9])([0-9][0-9])([0-9][0-9])([0-9][0-9])([0-9][0-9])([0-9][0-9][0-9])([^;]*)$/;\1-\2-\3T\4:\5:\6/ TZ +01:00'
이 방법은 다음 조건이 충족되는 경우에 작동합니다.
- 파일 이름의 타임스탬프는 +01:00 시간대에 있으며,
- 파일 이름과 경로 이름에는 ";" 문자가 포함되지 않습니다.
답변2
가정: 시간대 간 변환을 원하지 않고 파일 이름의 타임스탬프를 문자열로 구문 분석하기만 하면 됩니다. 또한 마지막 3자리는 중요하지 않으므로 무시해도 됩니다.
를 사용하여 스크립트를 find
호출합니다 .bash
find . -type f -exec bash -c '
pattern="([0-9]{4})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})[0-9]{3}"
fmt="\"%s\",\"%s\",%4d-%02d-%02dT%02d:%02d:%02d TZ +01:00\n"
for pathname do
! [[ "${pathname##*/}" =~ $pattern ]] && continue
printf "$fmt" "${pathname%/*}" "${pathname##*/}" "${BASH_REMATCH[@]:1}"
done' bash {} + >report.csv
이 find
명령은 .
현재 디렉터리( )에 있는 각 파일을 짧은 bash
스크립트에 제공합니다. 특정 파일 이름 접미사를 찾으려면 -name '*.jpg'
그 앞에 eg 를 추가하세요 -exec
.
주석이 포함된 스크립트 bash
:
# The regular expression that we'd like to match against each pathname.
pattern="([0-9]{4})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})[0-9]{3}"
# (year )(month )(day )(hour )(minute )(second ) last 3 digits ignored
# The format we'd like our output in (quoting the first two fields)
fmt="\"%s\",\"%s\",%4d-%02d-%02dT%02d:%02d:%02d TZ +01:00\n"
for pathname do
# If we can't match the pattern against the filename, ignore this file
! [[ "${pathname##*/}" =~ $pattern ]] && continue
# Output according to the format.
printf "$fmt" "${pathname%/*}" "${pathname##*/}" "${BASH_REMATCH[@]:1}"
done
출력 시 는 ${pathname%/*}
발견된 파일의 디렉터리(writable $( dirname "$pathname" )
)이고, ${pathname##*/}
는 발견된 파일의 파일 이름(writable $( basename "$pathname" )
)이며, ${BASH_REMATCH[@]:1}
정규식으로 캡처된 다양한 부분입니다.
전체 명령의 출력은 report.csv
명령 끝에서 리디렉션을 사용하여 기록 됩니다 find
.
예:
.
`-- dir
|-- 20180612074405680_ZTRDEFO_Blackgen.jpg
|-- file20180612074405680-1.txt
|-- file20180612074405680-10.txt
|-- file20180612074405680-2.txt
|-- file20180612074405680-3.txt
|-- file20180612074405680-4.txt
|-- file20180612074405680-5.txt
|-- file20180612074405680-6.txt
|-- file20180612074405680-7.txt
|-- file20180612074405680-8.txt
|-- file20180612074405680-9.txt
`-- some-other-file
명령을 실행하면 report.csv
다음이 생성됩니다.
"./dir","file20180612074405680-1.txt",2018-06-12T07:44:05 TZ +01:00
"./dir","file20180612074405680-2.txt",2018-06-12T07:44:05 TZ +01:00
"./dir","file20180612074405680-3.txt",2018-06-12T07:44:05 TZ +01:00
"./dir","file20180612074405680-4.txt",2018-06-12T07:44:05 TZ +01:00
"./dir","file20180612074405680-5.txt",2018-06-12T07:44:05 TZ +01:00
"./dir","file20180612074405680-6.txt",2018-06-12T07:44:05 TZ +01:00
"./dir","file20180612074405680-7.txt",2018-06-12T07:44:05 TZ +01:00
"./dir","file20180612074405680-8.txt",2018-06-12T07:44:05 TZ +01:00
"./dir","file20180612074405680-9.txt",2018-06-12T07:44:05 TZ +01:00
"./dir","file20180612074405680-10.txt",2018-06-12T07:44:05 TZ +01:00
"./dir","20180612074405680_ZTRDEFO_Blackgen.jpg",2018-06-12T07:44:05 TZ +01:00