根據文件名更改文件創建日期和時間
我正在將 Asterisk 通話錄音從我們的主伺服器複製到 samba 共享,並且創建日期和時間已更改為目前日期和時間。
文件格式為:
in-xxxxxxxxxx-xxxxxxxxxx-20211020-162749-**1634761669**.7921917.wav
粗體部分為 EPOCH 時間。我有數百個這樣的文件,我需要根據文件名中的 EPOCH 時間戳更改文件的創建日期。誰能幫我?
使用 GNU
touch
,您可以使用touch -d @1634761669.7921917 file
將文件的最後修改時間設置為指定的紀元時間(即使是亞秒級精度)。所以你可以這樣做
zsh
:#! /bin/zsh - ret=0 for file in *-<->.<->.wav; do t=${file:r} t=${t##*-} touch -d @$t -- $file || ret=$? done exit $ret
如果它真的是創建時間,通常稱為出生時間
ls -l --time=birth
,例如您想要更改的最新版本的 GNU所報告的那樣ls
,AFAIK 在 Linux 上是不可能的,除了將時鐘更改回那個時間並再次創建文件。但是,如果在 Linux(最新版本¹)上,您只能更改新
time
命名空間中的時鐘,以免影響全域系統的時鐘。例如,使用:
sudo unshare --time sh -c 'date -s @1634761669.7921917 && exec cp -a file file.new'
您將創建一個出生時間接近的
file.new
副本file``@1634761669.7921917
$ sudo unshare --time sh -c 'date -s @1634761669.7921917 && exec cp -a file file.new' $ ls -l --time=birth --time-style=+%s.%N file file.new -rw-r--r-- 1 stephane stephane 0 1642699170.474916807 file -rw-r--r-- 1 stephane stephane 0 1634761669.792191700 file.new
zsh
然後可以編寫上面的腳本:#! /bin/zsh - ret=0 for file in *-<->.<->.wav; do t=${file:r} t=${t##*-} unshare --time sh -c ' date -s "@$1" && exec cp -aTn -- "$2" "$2.new"' sh "$t" "$file" && mv -f -- "$file.new" "$file" || ret=$? done exit $ret
(並且需要作為 執行
root
)。修改此內容時的一些想法:
我剛剛意識到這會導致一個潛在的問題:該
unshare --time
hack 允許將出生時間設置為過去的某個任意時間,但這也會導致更改狀態時間(ls -lc
例如報告的時間)設置為過去,指定的時間,加上製作副本所用的時間)。該ctime也不意味著可以任意設置。通過這樣設置它,它可能會打破某些軟體可能對這些文件做出的假設。例如,備份軟體可能決定忽略它,因為它的 ctime 早於上次備份時間。
因此,最好確保 ctime 沒有在該命名空間中設置偽造的時鐘時間,例如,僅在過去創建文件,但在目前複製其內容:
unshare --time sh -Cc ' umask 77 && date -s "@$1" && : > "$2.new"' sh "$t" "$file" && cp -aT -- "$file" "$file.new" && mv -f -- "$file.new" "$file"
¹您需要 Linux 核心 5.6 或更高版本,並
CONFIG_TIME_NS
在核心和util-linux
2.36 或更高版本中啟用。