批量重命名文件,将两个特定单词从文件名移动到开头并删除最后一部分

批量重命名文件,将两个特定单词从文件名移动到开头并删除最后一部分

我的文件夹中有一堆视频,它们都以方括号内的随机代码结尾[_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

在里面重回伯恩之壳bash)...利用数组参数扩展

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将根据新行触发重命名。

这需要了解高级、批量文本编辑操作。

它不像其他答案那样是一个完全批处理解决方案,但在某些情况下可能更简单,并且可以在实际重命名之前提供文件列表的预览。

相关内容