![](/img/trans.png)
[英]How to rename all files in a directory adding prefix of current unix date
[英]Bulk rename files in Unix with current date as suffix
我正在嘗試使用日期后綴批量重命名當前文件夾中的所有文件:
rename 's/(.*)/$1_$(date +%F)/' *
但是該命令將info.txt
重命名為info.txt_1000 4 24 27 30 46 113 128 1000date +%F)
。 我希望結果為info.txt_2016-10-13
您希望按字面傳遞$1
來rename
,但是$(date +%F)
由shell擴展。 當您使用單引號,而僅使用雙引號時,后者將不會發生。 解決方案是使用雙引號並轉義$1
以使shell不會對其進行擴展。
rename "s/(.*)/\$1_$(date +%F)/" *
由於您說的是“在Unix中”,並且rename
命令不可移植(它實際上是perl軟件包的一部分),因此,這里的解決方案應可在更多環境中使用:
for file in *; do mv "$file" "${file}_$( date +%F )"; done
這將創建一個循環,然后將每個文件移到新名稱。 像問題一樣,它通過外殼進程替換使用date +%F
插入“完整日期”(YYYY-mm-dd)。 如John的回答所述,進程替換必須使用雙引號( "
)而不是單引號( '
),因為單引號會關閉shell解釋(這也適用於變量)。
如果目錄中包含太多文件,您的外殼程序將報錯,並顯示諸如“參數列表過長”之類的錯誤。 這是因為*
擴展到目錄的內容,所有這些都成為您正在運行的命令的參數。
要解決此問題,請創建一個腳本,然后通過xargs
,如下所示:
#!/bin/sh
if [ -z "$1" ]; then set *; fi # default to all files in curent directory
for file in "$@"; do mv "$file" "${file}_$( date +%F )"; done
對於腳本來說,使用ls
生成文件列表並不總是明智的選擇(在某些情況下它可以做一些奇怪的事情)。 使用find
代替:
find . -type f -not -name '*_20??-??-??' -print0 |xargs -0 sh /path/to/script.sh
請注意,該命令是遞歸的(通過在點后添加-maxdepth 1
更改該命令)。 find
是非常有能力的。 在此示例中,它將查找與外殼程序glob *_20??-??-??
不匹配的所有文件( -type f
)。 ( *
匹配任意數量的任何字符, ?
完全匹配任何字符之一,因此它匹配abc_2016-10-14
但不匹配abc_2016-10-14-def
)。 這使用find … -print0
和xargs -0
來確保正確保留間距(而不是空格,它們使用空字符作為分隔符)。
您也可以使用perl rename
:
find . -type f -not -name '*_20??-??-??' -print0 |xargs -0 \
rename "s/(.*)/\$1_$( date +%F )/"
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.