簡體   English   中英

以當前日期為后綴的Unix中的批量重命名文件

[英]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

您希望按字面傳遞$1rename ,但是$(date +%F)由shell擴展。 當您使用單引號,而僅使用雙引號時,后者將不會發生。 解決方案是使用雙引號並轉義$1以使shell不會對其進行擴展。

rename "s/(.*)/\$1_$(date +%F)/" *

便攜式Posix外殼解決方案

由於您說的是“在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 … -print0xargs -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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM