フォルダとサブフォルダを繰り返し、タイムスタンプを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

関連情報