我的文件夹中有一堆视频,它们都以方括号内的随机代码结尾[_qj3ZkAR2tE]
,即,在此部分之前,我想将两个单词移动到文件名的开头。我想要完成的示例:
The Ultimate Fallacy Lesson 1 [code*123].mp4
How to Structure Concrete Lesson 2 [code_412].mp4
会成为
Lesson 1 The Ultimate Fallacy.mp4
Lesson 2 How to Structure Concrete.mp4
等等。如何使用重命名、qmv、shell 脚本或任何可以解决问题的方法来实现这一点?如果需要,我可以用符号或其他东西替换空格。
答案1
使用基于 Perl 的rename
命令(用于-n
试运行)并假设您的“单词”是由一个空格分隔的非空白字符序列:
$ rename -n 's/(.*) (\S* \S*) \[.*?\]/$2 $1/' -- *.mp4
rename(How to Structure Concrete Lesson 2 [code_412].mp4, Lesson 2 How to Structure Concrete.mp4)
rename(The Ultimate Fallacy Lesson 1 [code*123].mp4, Lesson 1 The Ultimate Fallacy.mp4)
答案2
for f in *.mp4
do
IFS='. ' read -r -a a <<< "$f"
f1="${a[-4]} ${a[-3]} ${a[@]::${#a[@]}-4}.${a[-1]}"
echo mv -nv -- "$f" "$f1"
done
注意:echo
是为了安全的试运行而添加的...当对输出满意时将其删除,以便进行实际的重命名。
示范:
$ for f in *.mp4
do
IFS='. ' read -r -a a <<< "$f"
f1="${a[-4]} ${a[-3]} ${a[@]::${#a[@]}-4}.${a[-1]}"
mv -nv -- "$f" "$f1"
done
renamed 'How to Structure Concrete Lesson 2 [code_412].mp4' -> 'Lesson 2 How to Structure Concrete.mp4'
renamed 'The Ultimate Fallacy Lesson 1 [code*123].mp4' -> 'Lesson 1 The Ultimate Fallacy.mp4'
怎么运行的:
将为for f in *.mp4 ...
每个文件名分配(非隐藏,即不以点开头.
.mp4
)在当前工作目录中的扩展名中,f
每次循环运行一个文件名并将其添加到变量中。
然后,变量中的文件名f
被分成几部分(字)围绕点.
和空格字符,通过设置内部字段分隔符对这些字符进行
IFS='. '
阅读时这里字符串放入一个索引数组元素中read -r -a
。
以文件名The Ultimate Fallacy Lesson 1 [code*123].mp4
为例,之后:
IFS='. ' read -r -a a <<< "$f"
该数组a
将如下所示:
$ declare -p a
declare -a a=([0]="The" [1]="Ultimate" [2]="Fallacy" [3]="Lesson" [4]="1" [5]="[code*123]" [6]="mp4")
... 并且其元素可以通过索引从左到右调用(从头到尾) 喜欢:
$ echo "${a[0]} ${a[1]}"
The Ultimate
... 或从右到左(从最后到第一) 喜欢:
$ echo "${a[-1]} ${a[-2]}"
mp4 [code*123]
...或按范围使用${a[@]:start_index:length}
(如果start_index
省略,则0
假定) 喜欢:
$ echo "${a[@]:0:2}"
The Ultimate
$
$ echo "${a[@]::2}"
The Ultimate
...相对于数组长度的范围${#a[@]}
也可以用以下方式调用:
$ echo "${a[@]::${#a[@]}-4}"
The Ultimate Fallacy
...因此将变量赋值给f1
:
f1="${a[-4]} ${a[-3]} ${a[@]::${#a[@]}-4}.${a[-1]}"
...看起来会像这样:
$ declare -p f1
declare -- f1="Lesson 1 The Ultimate Fallacy.mp4"
通知壳牌(zsh
) 用户:
您可以使用内置 shell 函数利用扩展的 glob 模式执行相同的操作zmv
像这样:
% autoload zmv
%
% zmv -n -- '(* *) (* * )(\[*\])(.mp4)' '$2$1$4'
mv -- 'How to Structure Concrete Lesson 2 [code_412].mp4' 'Lesson 2 How to Structure Concrete.mp4'
mv -- 'The Ultimate Fallacy Lesson 1 [code*123].mp4' 'Lesson 1 The Ultimate Fallacy.mp4'
该-n
选项用于安全的试运行...当对输出满意时,用-v
(详细程度) 以便真正进行重命名。
答案3
for filename in *.mp4; do
# Get extention (element after last dot)
ext="${filename##*.}"
# Remove token and all characters after ' [' token
fname_wo_brackets="${filename%% [*}"
# Get last word
last_word_1="${fname_wo_brackets##* }"
# Remove last word
fname_wo_brackets="${fname_wo_brackets% *}"
# Get last word
last_word_2="${fname_wo_brackets##* }"
# Remove last word
fname_wo_brackets="${fname_wo_brackets% *}"
# Create new filename
new_filename="$last_word_2 $last_word_1 $fname_wo_brackets.$ext"
# Print current and future filnames
echo "rename '$filename' to '$new_filename'"
# Rename (without hash)
# mv "$filename" "$new_filename"
done
如果您同意建议的文件名,请删除mv
命令前的井号。
答案4
如果你知道如何使用 Vim 文本编辑器,那么
vidir *.mp4
可以通过在文本编辑器中更改带有文件名的文本文件来帮助您以交互方式批量重命名文件。保存并退出vidir
将根据新行触发重命名。
这需要了解高级、批量文本编辑操作。
它不像其他答案那样是一个完全批处理解决方案,但在某些情况下可能更简单,并且可以在实际重命名之前提供文件列表的预览。