将文件名中的 EPOCH 字符串转换为可读格式

将文件名中的 EPOCH 字符串转换为可读格式

我对 Unix 的了解不是很好。我正在尝试编写一个 shell 脚本来重命名目录中的一组文件,例如1709532255.mp4to 20240304_070415.mp4,其中1709532255始终是纪元时间。

我找到

date -d @1708532255 +'%Y%m%d_%H%M%S'

...给了我想要的格式,但我无法让它在脚本中工作。

这是我的脚本:

#!/bin/bash
for file in /media/HAVideo/Eingang/Test/2/*.mp4
do
filename=`echo "${file}" | cut -d'.' -f1`
readable=`date -d @$filename +"%Y%m%d%H%M%S"`
mv "${file}" "${readable}"
done

输出是:

...
date: invalid date '@/media/HAVideo/Eingang/Test/2/1709532255'
mv: can't rename '/media/HAVideo/Eingang/Test/2/1709532255.mp4': No such file or directory
...

答案1

您刚刚错过了cd

#!/bin/bash

cd /media/HAVideo/Eingang/Test/2/ || exit # <- what changed
for file in *.mp4
do
filename=`echo "${file}" | cut -d'.' -f1`
readable=`date -d @$filename +"%Y%m%d%H%M%S.mp4"`
mv "${file}" "${readable}"
done

但有一些问题。

使用$( )反引号代替。并正确缩进。

http://mywiki.wooledge.org/BashFAQ/082

更好的版本:

#!/bin/bash -

cd /media/HAVideo/Eingang/Test/2/ || exit
for file in *.mp4 ; do
    mv -- "$file" "$(date -d "@${file%.*}" +"%Y%m%d%H%M%S.mp4")"
done

${file%.*}是一个内置的参数扩展

看:http://mywiki.wooledge.org/BashFAQ/073
LESS='+/Parameter Expansion' man bash
另请参阅wiki.bash-hackers.org/syntax/pe

由于这是一个标准sh运算符(来自 ksh)并且该代码中没有 bashism,因此您可以将 shebang 更改为#! /bin/sh -并删除 bash 依赖项。不过,这date -d是一种非标准的 GNU 主义,您可以通过使用printf '%(format)T'最新版本的 bash(从 ksh93 复制)来避免这种情况。

答案2

zsh

$ zmodload zsh/datetime
$ autoload zmv
$ cd /media/HAVideo/Eingang/Test/2/
$ zmv -n '(<->)(.mp4)' '$(strftime %Y%m%d_%H%M%S $1)$2'
mv -- 1709532255.mp4 20240304_060415.mp4

-n如果满意,请删除(试运行))。

请注意,虽然 1709532255 与时区无关,但20240304_060415它不是并且是不明确的。您可以通过使用 ISO8601 样式的日期格式消除歧义并仍然使用本地时间,其中包含 UTC 偏移量,%Y%m%d_%H%M%S例如%FT%T%z,我得到的2024-03-04T06:04:15+0000和你可能得到的2024-03-04T07:04:15+0100相同的时间戳,但在两个不同的时区。

答案3

您看到错误的原因:

date: invalid date '@/media/HAVideo/Eingang/Test/2/1709532255'

是因为您根据命令传递了文件的完整路径,减去扩展名cut

[...snipped out irrelevant parts...]
filename=`echo "${file}" | cut -d'.' -f1`
...
readable=`date -d @$filename +"%Y%m%d%H%M%S"`

正在评估:

readable=`date -d @/media/HAVideo/Eingang/Test/2/1709532255 +"%Y%m%d%H%M%S"`

因此,filename/media/HAVideo/Eingang/Test/2/1709532255

你的脚本大部分都有效。我修改了该filename=...行以仅检索文件的基本名称,而不是完整路径:

#!/bin/bash
for file in /media/HAVideo/Eingang/Test/2/*.mp4
do
filename=`basename "${file}" | cut -d'.' -f1`
readable=`date -d @$filename +"%Y%m%d%H%M%S"`
mv "${file}" "${readable}"
done

当然,您可以进一步删除不必要的内容,cut因为basename可以删除文件扩展名,并重命名变量,以便代码更清晰一些:

for src in /media/HAVideo/Eingang/Test/2/*.mp4
do
  epoch="$(basename "$src" .mp4)"
  dst="$(date -d "@$epoch" +"%Y%m%d%H%M%S")"
  mv "$src" "$dst"
done

答案4

使用(可在任何操作系统中使用)。

perl -MTime::Piece -e '
    for (@ARGV) {
        my $file = $_;
        s/\..*$//;
        rename $file, Time::Piece->strptime($_, "%s")->strftime("%Y%m%d_%H%M%S")
    }
' *.mp4

Time::Piece的模块是用Perl打包的,无需安装。

相关内容