我对 Unix 的了解不是很好。我正在尝试编写一个 shell 脚本来重命名目录中的一组文件,例如1709532255.mp4
to 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打包的,无需安装。