用于遍历文件夹和子文件夹、将时间戳转换为 UTC 格式并导出 .csv 文件的 shell 脚本

用于遍历文件夹和子文件夹、将时间戳转换为 UTC 格式并导出 .csv 文件的 shell 脚本

我有大量的图像文件(大约 100 000 个)保存在 50 个文件夹和子文件夹中,我需要编写一个脚本才能自动处理这些数据

我正在尝试写一个外壳脚本对于一个有点复杂的任务,我现在正在努力让它以正确的方式运行。因此,为了给您尽可能最好的描述,我将写下我想用这个脚本完成的主要事情,如下所示:

首先:脚本必须遍历文件夹和子文件夹并提取文件名和完整路径

第二:文件名包含时间和日期信息。即: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

假设:您不想在时区之间进行转换,只需将文件名中的时间戳解析为字符串即可。另外,最后三位数字并不重要,可以被丢弃。

使用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%/*}是找到的文件的目录(可写$( dirname "$pathname" )),${pathname##*/}是找到的文件的文件名(可写$( 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

相关内容