如何批量重命名與 Linux 中的模式匹配的所有文件?
我有一個文件夾,其中包含許多
.mkv
我想重命名的文件,而無需手動這樣做。模式是這樣的:
... [XVC]_Control_-_10_-_Doctors_[SCB055Y].mkv [XVC]_Control_-_11_-_Engineers_[50OPZ00].mkv ...
我希望結果是:
... Control-10-Doctors.mkv Control-11-Engineers.mkv ...
我已經嘗試通過 and 使用和
find
管道它,但我似乎無法讓它工作。sed``tr
這是我迄今為止嘗試過的:
find . -iname "*.mkv" -exec sed -e 's/\[[^][]*\]//g' {} \; find . -type f "*mkv" | sed 's/\[[^][]*\]//g' | tr -d '_' find . "*.mkv" -type f -print0 | xargs -0 sed -i '' -e 's/\[[^][]*\]//g' | tr -d '_' find . -iname "*.mkv" -exec rename 's/\[[^][]*\]//g' .mkv '{}' \; find . -iname "*.mkv" -exec rename -n 's/\[[^][]*\]//g' {} ";"
還有其他幾個,但似乎沒有一個有效。我發現下面的命令命令有效,令人費解:
(input) echo '[XVC]_Control_-_10_-_Doctors_[SCB055Y].mkv' | sed 's/\[[^][]*\]//g' | tr -d '_'` (output) Control-10-Doctors.mkv
編輯:
$ file $(which rename) /usr/bin/rename: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=d7b5a08ee8556c59dbdda26e998e20d4762c2bbc, for GNU/Linux 3.2.0, stripped
rename -n 's/\[.+?\]//g; s/_//g' *mkv rename: not enough arguments Try 'rename --help' for more information.
這將與 perl-rename 一起使用(稱為
rename
orprename
或perl-rename
取決於您的發行版):$ rename -n 's/\[.+?\]//g; s/_//g' *mkv [XVC]_Control_-_10_-_Doctors_[SCB055Y].mkv -> Control-10-Doctors.mkv [XVC]_Control_-_11_-_Engineers_[50OPZ00].mkv -> Control-11-Engineers.mkv
或者,寫一個小循環:
find . -iname "*.mkv" -print0 | while IFS= read -rd '' file; do newName=$(printf -- '%s\n' "$file" | perl -pe 's/\[.+?\]//g; s/_//g') echo mv -- "$file" "$newName" done
如果看起來正確,請刪除
echo
並再次執行它以實際重命名文件。如果這為您提供了所需的輸出,請再次執行它而不-n
實際重命名文件。由於各種原因,您的命令不起作用。
find . -iname "*.mkv" -exec sed -e 's/\[[^][]*\]//g' {} \;
這是
sed
在文件本身上執行命令,因此它只會更改文件的內容,而不是名稱。甚至沒有,因為您沒有使用-i
這意味著它只是將更改的內容列印到標準輸出。 2.find . -type f "*mkv" | sed 's/\[[^][]*\]//g' | tr -d '_'
在這裡,
find
正在列印文件名,但這些只是作為文本(流)傳遞給sed
它修改其輸入,但不改變文件名。它與 相同echo foo | sed 's/f/b/'
。foo
如果碰巧在那裡,這不會重命名一個名為的文件。 3.find . "*.mkv" -type f -print0 | xargs -0 sed -i '' -e 's/\[[^][]*\]//g' | tr -d '_'
在這裡,
sed
再次在文件上執行,所以它基本上是相同的,除瞭如果它的任何內容匹配它會實際修改文件。由於這些是二進製文件,您不太可能但並非不可能實際修改它們。 4.find . -iname "*.mkv" -exec rename 's/\[[^][]*\]//g' .mkv '{}' \;
這個實際上能夠重命名文件,但是由於您將字元串
.mkv
作為第一個參數傳遞給rename
命令,它試圖重命名一個名為.mkv
. 由於您可能沒有這樣的文件,因此它什麼也不做。第二個參數 ,'{}'
被忽略。這會奏效:find . -iname "*.mkv" -exec rename 's/\[[^][]*\]//g' {} \;
但它會將文件重命名為
_Control_-_10_-_Doctors_.mkv
and_Control_-_11_-_Engineers_.mkv
因為你沒有處理_
那個文件。 5.find . -iname "*.mkv" -exec rename -n 's/\[[^][]*\]//g' {} ";"
這個應該有效!就像上面 4 中描述的那樣,它只是沒有進行正確的重命名。