重新命名多個檔案以減少檔案名稱中的數字?

重新命名多個檔案以減少檔案名稱中的數字?

我的文件命名不正確,但 -1 未同步。問題是我需要重命名其中的數千個。

  • DBGC180_805754
  • DBGC180_805755
  • DBGC180_805756

  • DBGC180_805753
  • DBGC180_805754
  • DBGC180_805755

我更喜歡使用 bash 腳本或 unix 命令。

答案1

你可以這樣做:

# {smallestfilenum..largestfilenum}

for i in {805754..999999}; do 
   mv "DBGC180_$i" "DBGC180_$(($i-1))";
done

使用較小的數字(例如 805754..805758)進行嘗試,以確保它按您的預期工作。請注意,如果具有新名稱的檔案已存在,它將被覆蓋。

答案2

  1. 將要重新命名的檔案移至子目錄中(不更改其名稱)。
  2. 將子目錄中的檔案重新命名到原始目錄中。

我推薦步驟 1 有兩個原因,即使沒有它也是可能的:

  • 如果命令被中斷,您可以從上次中斷的地方繼續,因為哪些檔案已被重新命名、哪些檔案尚未重新命名是顯而易見的。
  • 您無需擔心以錯誤的順序重新命名並覆蓋現有文件之一。

未經測試的 shell 片段(依賴要遞減的數字永遠不會有任何前導零的事實):

mkdir to_decrement
for x in DBGC180_80575[4-9] DBGC180_8057[6-9]? DBGC180_805[8-9]?? DBGC180_80[6-9]??? DBGC180_8[1-9]???? DBGC180_9?????; do
  mv "$x" to_decrement/
done
cd to_decrement
for x in *; do
  number="${x##*_}"
  mv -i -- "$x" "../${x%_*}_$((number-1))"
done
cd ..
rmdir to_decrement

桀騁,你可以讓這變得更簡單,這要歸功於它數字範圍全局, 它是內建mv這避免了遇到命令列長度限制,及其基於模式的批次重命名功能。在 zsh 中:

autoload -U zmv
zmodload -m -F zsh/files b:zf_\*
mkdir to_decrement
zf_mv DBGC180_<805754-> to_decrement/
zmv 'to_decrement/(*)_(*)' '${1}_$(($2-1))'
rmdir to_decrement

答案3

因此,您想要重新命名DBGC180_805754DBGC180_805753...55to...54等等。這就是我要解決的問題。

首先,將此腳本放在您的某個位置PATH,並呼叫它waltinator

#!/bin/bash
#step through the parameters 
while [[ -n "$1" ]] ; do
    oldname="$1"
    # shift the arguments left
    shift;
    # strip off the fixed part of the old name
    oldnum=${oldname##DBGC180_}
    # decrement the number (this is what was wanted, right?)
    newnum=$(( $oldnum - 1 ))
    # build the new, improved filename
    newname="DBGC180_$newnum"
    if [[ -f "$newname" ]] ; then
        printf "Cannot rename $oldname to $newname, $newname exists.\n" >&2
        exit 1
    fi
    mv --no-clobber "$oldname" "$newname"
done
exit 0

對於下一步,假設腳本位於 中$HOME/bin/waltinator,並且您有 does chmod +x $HOME/bin/waltinator

find . -type f -name 'BDGC180_[0-9][0-9][0-9][0-9][0-9][0-9]` -print | \
    sort | \
    xargs $HOME/bin/waltinator

尋找find檔案(無特定順序),其名稱與 shell glob 模式「BDGC180_後面跟著 6 位元數字 ( ) 相符。由於我們需要一個排序清單(在重命名之前重命名為[0-9]會失敗),因此我們執行through的輸出。然後,如果需要縮短參數列表,我們將獲取(排序的)檔案名稱列表,並建立一個命令將(排序的)檔案名稱列表傳遞給Read 。...97...96...96findsortxargs$HOME/bin/waltinatorman xargs

為此,請閱讀:

for page in bash mv find sort xargs ; do
    man "$page"
done   

答案4

用於rename將每個數字替換為自身減 1。

$ rename -v 's/\d{6}/sprintf("%06",($&-1))/e'    

筆記

  • rename使用 Perl 表達式來重新命名檔案名稱。
  • s指定rename將替換部分或全部與正規表示式模式相符的檔案名稱。
  • Perl 替換表達式的結構如下。
    • s/PATTERN/REPLACEMENT/MODIFIER
  • \d{6}rename是將搜尋和取代的模式。這是 6 位十進制數字。
  • $是儲存匹配的子字串的變數\d{6}(在本例中「子字串」是一個 int)。
  • sprintf("%06",($&-1))檢索儲存在 中的值$,將其遞減,然後傳回該值作為替換值。是%06用來處理前導零的。
  • e指定rename將替換計算為 Perl 語句,並使用其傳回值作為替換文字。
  • -vrenameecho 執行它正在做的事情。

如果您想更加安全,請使用該標誌-n,這樣它rename只會告訴您它將做什麼,而不是執行它。

這似乎只適用於遞減,因此請小心處理。

相關內容