根据文件名更改文件创建日期和时间

Gre*_*don 4 timestamps files

我正在将 Asterisk 通话录音从我们的主服务器复制到 samba 共享,并且创建日期和时间已更改为当前日期和时间。

文件格式为:in-xxxxxxxxxx-xxxxxxxxxx-20211020-162749-1634761669.7921917.wav

粗体部分为EPOCH时间。我有数百个这样的文件,我需要根据文件名中的 EPOCH 时间戳更改文件的创建日期。谁能帮我?

Sté*_*las 11

使用 GNU touch,您可以将文件的最后修改时间touch -d @1634761669.7921917 file设置为指定的纪元时间(即使使用亚秒精度,如下所示)。

\n

所以你可以这样做zsh

\n
#! /bin/zsh -\nret=0\nfor file in *-<->.<->.wav; do\n  t=${file:r} t=${t##*-}\n  touch -d @$t -- $file || ret=$?\ndone\nexit $ret\n
Run Code Online (Sandbox Code Playgroud)\n

如果确实是创建时间(通常称为出生时间)ls -l --time=birth ,例如您想要更改的GNU 最新版本的报告ls,那么在 Linux 上除了将时钟更改回该时间并创建再次归档。

\n
\n

下面的部分是错误的,它并没有像我最初认为的那样改变名称空间中的时间。有关详细信息,请参阅@Busindre 的答案

\n \n如果在 Linux(最新版本\xc2\xb9)上,您只能更改新的“time”命名空间中的时钟,以免全局影响系统时钟。\n

例如,与:

\n
sudo unshare --time sh -c \'date -s @1634761669.7921917 && exec cp -a file file.new\'\n
Run Code Online (Sandbox Code Playgroud)\n

您将创建一个出生时间接近的file.new副本file@1634761669.7921917

\n
$ sudo unshare --time sh -c \'date -s @1634761669.7921917 && exec cp -a file file.new\'\n$ ls -l --time=birth --time-style=+%s.%N file file.new\n-rw-r--r-- 1 stephane stephane 0 1642699170.474916807 file\n-rw-r--r-- 1 stephane stephane 0 1634761669.792191700 file.new\n
Run Code Online (Sandbox Code Playgroud)\n

上面的脚本zsh可以写成:

\n
#! /bin/zsh -\nret=0\nfor file in *-<->.<->.wav; do\n  t=${file:r} t=${t##*-}\n  \n  unshare --time sh -c \'\n    date -s "@$1" && exec cp -aTn -- "$2" "$2.new"\' sh "$t" "$file" &&\n    mv -f -- "$file.new" "$file" || ret=$?\ndone\nexit $ret\n
Run Code Online (Sandbox Code Playgroud)\n

(并且需要作为 运行root)。

\n

重新审视这一点时又想到了一些:

\n

我刚刚意识到这会导致一个潜在的问题:unshare --time黑客允许将出生时间设置为过去的某个任意时间,但这也会导致更改状态时间(例如报告的时间ls -lc)设置为过去的时间,即指定的时间,加上制作副本所需的时间)。

\n

ctime也不意味着可以任意设置通过像这样将其设置为过去,它可能会打破某些软件可能对这些文件所做的假设。例如,备份软件可能决定忽略它,因为它的 ctime 早于上次备份时间。

\n

因此,最好确保 ctime 未在该名称空间中设置为伪造的时钟时间,例如,仅在过去创建文件,但在当前复制其内容:

\n
unshare --time sh -Cc \'\n  umask 77 && date -s "@$1" && : > "$2.new"\' sh "$t" "$file" &&\n  cp -aT -- "$file" "$file.new" &&\n  mv -f -- "$file.new" "$file"\n
Run Code Online (Sandbox Code Playgroud)\n
\n

\xc2\xb9 您需要 Linux 内核 5.6 或更高版本,并CONFIG_TIME_NS在内核 2.36 或更高版本中启用util-linux

\n \n