Awk
從儲存為文件名的日期設置文件修改日期
我有很多文件,其中文件名包含文件創建日期(
IMG_YYYYMMDD_hhmmss.jpg
):IMG_20171015_133516.jpg IMG_20171015_133827.jpg IMG_20171015_142634.jpg IMG_20171015_142834.jpg IMG_20171015_142857.jpg
但實際文件創建日期不同。我需要從文件名將其設置回日期。
我知道如何將所有文件的日期更改為目前日期:
find -type f -exec touch {} \;
以及如何解析文件名以獲取正確格式的日期
touch -t
echo IMG_20171015_133516.jpg | awk -F_ '{print $2 substr($3,0,4) "." substr($3,5,2)}' 201710151335.16
但我不知道如何將這些命令組合在一起來更改所有文件。
find -type f -exec touch -t"$(echo '{}' | awk -F_ '{print $2 substr($3,0,4) "." substr($3,5,2)}')" {} \;
返回
觸摸:無效的日期格式“。”
在外殼中:
for f in ./IMG_*.jpg ; do t=${f##*/} touch "$f" -t "${t:4:8}${t:13:4}.${t:17:2}" done
Bash、ksh、zsh 等具有
${var:n:m}
子字元串擴展,如果您需要遞歸執行,請啟用globstar
並**/IMG_*.jpg
改為使用。這樣做也
find
需要外殼:$ find -name "IMG_*.jpg" -exec bash -c ' for f; do t=${f##*/}; touch "$f" -t "${t:4:8}${t:13:4}.${t:17:2}" ; done ' sh {} \+
腳本後 Bash 的第一個參數轉到
$0
變數,該變數通常包含 shell 名稱。其餘的轉到位置參數$1
,$2
等和for f
orfor f in "$@"
循環它們。這裡的構造相當普遍(至少在 unix.SE 答案中)。這裡循環的主要部分與第一個範例相同。
find
您問題中的find .. -exec touch -t"$(...)" {} \;
命令不起作用,因為命令替換用雙引號引起來,因此在find
執行之前它會被擴展。字面意思是通過{}
管道傳輸到awk
,並且恰好awk
腳本只列印一個點。如果您確實將命令替換放在單引號中,它將按
touch
原樣傳遞(find
只會替換{}
)。touch
會得到參數-t$(echo ...)
,美元符號,括號和所有。find
它本身不會通過 shell 執行命令,我們需要像上面那樣顯式地執行它。在單引號範例中:
$ find -name x -exec echo 'hello $(foo {})' \; hello $(foo ./x)