Shell-Script

通過用文本文件中的對應字元串替換文件名中的數字來重命名一堆文件

  • December 23, 2021

我有大量要重命名的文件。每個文件名都包含一個數字 (xxx) FIXED_PART_xxx_UNIQUE_PART:.

我還有一個文本文件,每行都有一個數字和一個字元串:

001 string001
002 string002
...
112 string112

每個文件都有一個條目,但不一定每個條目都有一個文件。我想通過解析xxx部分並將其替換為文件中的字元串來重命名每個文件。

最好的方法是什麼?

編輯:實際的文件名如下所示:

Berlin_Ost_034_some_variable_text.jpg

因此在這種情況下,固定部分也包含下劃線,但每個文件夾都相同。xxx 部分僅由數字組成。

輸出將用於此文件

Berlin_Ost_Sommer_some_variable_text.jpg

我說的是200個文件

文本文件包含一行:034 Sommer

這就是為什麼文件中的 034 部分被 Sommer 替換的原因

該文件包含各種字元串,但只有字元和數字以及德語變音符號。第一部分始終是一個數字。這是我正在使用的文件之一的一部分

033 Winter
034 Sommer
035 Herbst
036 Frühling
037 Abends.kurz.vor.Sonnenaufgang

我正在使用 linux

您可以遍歷字元串列表中的每個條目,重命名任何匹配的文件。這可以壓縮成一行,但我在這裡將其打開,以便我可以附加註釋:

while IFS=' ' read -r key value                            # Extract the key and value
do
   for file in *_"$key"_*                                 # Loop across all matches
   do
       [ -f "$file" ] &&
           mv -- "$file" "${file/_${key}_/_${value}_}"    # Replace key with value
   done
done <keysandvalues                                        # Read the file of matches

替換錶達式將僅替換第一次出現的鍵,並且兩邊必須用下劃線限定。鍵和值都不能包含/.

遍歷替換文件的一個副作用是,如果您的文件名包含兩個替換字元串(例如,Berlin_033_other_035_text.jpg),那麼兩者都將在匹配時被替換(導致此處為Berlin_Winter_other_Herbst_text.jpg)。如果有問題,將重命名的文件移動到單獨的目錄可以解決此問題。

假設zsh字元串不包含空格或製表符:

autoload -Uz zmv
typeset -A mapping=($(<mapping.txt))
zmv -n '(*_)([0-9](#c3))(_*.jpg)' '$1${mapping[$2]-$2}$3'

-n如果滿意,請刪除(試執行)。

對於包含多個下劃線之間的 3 位數字序列的文件名,最右邊的將被替換。Using${mapping[$2]-$2}確保如果在映射中找不到該數字序列,那麼它將保持原樣。

如果所有文件都具有相同的前綴,您還可以執行以下操作:

zmv -n '(Berlin_Ost_)([0-9](#c3))(_*.jpg)' '$1${mapping[$2]-$2}$3'

如果字元串可能包含空格或空格(開頭或結尾除外),則可以將關聯數組建構為:

typeset -A mapping
while read -r key value; do mapping[$key]=$value; done < mapping.txt

反而。

要替換文件名中所有出現的 3 位數字,您可以執行以下操作:

zmv -n '*.jpg' '${f//(#m)[0-9](#c3)/${mapping[$MATCH]-$MATCH}'

在這種情況下,我們不會在兩邊尋找下劃線。我們可以這樣做:

zmv -n '*.jpg' '${f//(#b)_([0-9](#c3))_/${mapping[$match[1]]-$match[1]}'

但是,雖然這將取代兩者001002in foo_001_bar_002_baz.jpg,但不會 in ,foo_001_002_bar.jpg因為第二個_將包含在第一場比賽中,因此不能成為以後比賽的一部分。

引用自:https://unix.stackexchange.com/questions/683642