폴더와 하위 폴더를 반복하고, 타임스탬프를 UTC 형식으로 변환하고, .csv 파일을 내보내는 셸 스크립트

폴더와 하위 폴더를 반복하고, 타임스탬프를 UTC 형식으로 변환하고, .csv 파일을 내보내는 셸 스크립트

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'

이 방법은 다음 조건이 충족되는 경우에 작동합니다.

  1. 파일 이름의 타임스탬프는 +01:00 시간대에 있으며,
  2. 파일 이름과 경로 이름에는 ";" 문자가 포함되지 않습니다.

답변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

관련 정보