我有一堆视频文件,其中所有文件名都是无用的乱码。
1) 是否有一个简单的命令可以将文件夹中所有文件的名称更改为哈希值,例如 (sha256).mp4?我不想移动/复制/修改任何文件,只想重命名它们。
2) 是否可以修改 1) 中的命令,只将哈希值添加到原始文件名的末尾?例如 (原名)_(sha256).mp4
我对 Ubuntu/Linux 还很陌生,非常希望能够解释一下该命令的每个部分的作用。
答案1
您实际上可以使用以下命令执行此rename
操作:
rename 'chomp(my $new=`sha256sum "$_" | cut -d" " -f1`); s/.*/$new.mp4/' *mp4
要在实际重命名之前预览它将执行的操作,请使用-n
。例如:
$ ls
'my movie file01.mp4' 'my movie file05.mp4' 'my movie file09.mp4'
'my movie file02.mp4' 'my movie file06.mp4' 'my movie file10.mp4'
'my movie file03.mp4' 'my movie file07.mp4'
'my movie file04.mp4' 'my movie file08.mp4'
$ rename -n 'chomp(my $new=`sha256sum "$_" | cut -d" " -f1`); s/.*/$new.mp4/' *mp4
my movie file01.mp4 -> 6a260f4adeb47000afeb9c53029ce0e14b6ea80be5c649ecdb155c8e7cfa1496.mp4
my movie file02.mp4 -> 14f24228ead10d639ef3db11ea09c6216aa80879327a2a57fb549e6474fb05b0.mp4
my movie file03.mp4 -> 6c9ecec6a75e217fa1786dd6f920a5c1db8473f17447595e0d33d7fc3530453a.mp4
my movie file04.mp4 -> 96a29ae5bc3a5e35537bcea1068c746ddba205d17fcc8e522a52402c7ed69927.mp4
my movie file05.mp4 -> 189207823129b57e52c86a743ea7154f65b8eccb5182f322abc3aae35f14057d.mp4
my movie file06.mp4 -> 93be0fd15be56bb22af94a0a0aa272d56f61e77160f1170305d41166d6135913.mp4
my movie file07.mp4 -> 05c92b5632414f14445af3facdb0e187746b3b0f40bad94a5f351aeb7f9a8847.mp4
my movie file08.mp4 -> 0d3cf9c165d4c18af8922b8daa9a6b1031c6762d179fb910b968d60af9aed255.mp4
my movie file09.mp4 -> da04afebaec6ea3d43dc3a0e66b790ab13751b00fd81aa1f882986c097c36298.mp4
my movie file10.mp4 -> 47bf532970d3e759346462a85d15ab9d9171c5a7688a6e90a1e976e071ecd167.mp4
并保留原来的名字:
$ rename -n 'chomp(my $new=`sha256sum "$_" | cut -d" " -f1`); s/.*/$_ $new.mp4/' *mp4
my movie file01.mp4 -> my movie file01.mp4 6a260f4adeb47000afeb9c53029ce0e14b6ea80be5c649ecdb155c8e7cfa1496.mp4
my movie file02.mp4 -> my movie file02.mp4 14f24228ead10d639ef3db11ea09c6216aa80879327a2a57fb549e6474fb05b0.mp4
my movie file03.mp4 -> my movie file03.mp4 6c9ecec6a75e217fa1786dd6f920a5c1db8473f17447595e0d33d7fc3530453a.mp4
my movie file04.mp4 -> my movie file04.mp4 96a29ae5bc3a5e35537bcea1068c746ddba205d17fcc8e522a52402c7ed69927.mp4
my movie file05.mp4 -> my movie file05.mp4 189207823129b57e52c86a743ea7154f65b8eccb5182f322abc3aae35f14057d.mp4
my movie file06.mp4 -> my movie file06.mp4 93be0fd15be56bb22af94a0a0aa272d56f61e77160f1170305d41166d6135913.mp4
my movie file07.mp4 -> my movie file07.mp4 05c92b5632414f14445af3facdb0e187746b3b0f40bad94a5f351aeb7f9a8847.mp4
my movie file08.mp4 -> my movie file08.mp4 0d3cf9c165d4c18af8922b8daa9a6b1031c6762d179fb910b968d60af9aed255.mp4
my movie file09.mp4 -> my movie file09.mp4 da04afebaec6ea3d43dc3a0e66b790ab13751b00fd81aa1f882986c097c36298.mp4
my movie file10.mp4 -> my movie file10.mp4 47bf532970d3e759346462a85d15ab9d9171c5a7688a6e90a1e976e071ecd167.mp4
这里的解释有点复杂,因为它需要理解一些基本的 Perl。主要思想是:
my $new=`sha256sum "$_" | cut -d" " -f1`
sha256sum
:这将在每个输入文件上运行命令($_
Perl magic 表示“当前事物”),并cut
仅保留哈希值。举例来说:$ sha256sum my\ movie\ file01.mp4 6a260f4adeb47000afeb9c53029ce0e14b6ea80be5c649ecdb155c8e7cfa1496 my movie file01.mp4 $ sha256sum my\ movie\ file01.mp4 | cut -d" " -f1 6a260f4adeb47000afeb9c53029ce0e14b6ea80be5c649ecdb155c8e7cfa1496
这
chomp()
只是从命令的输出中删除尾随的换行符。结果存储在变量中$new
。s/.*/$new.mp4/'
:用名称替换所有内容(.*
)$new
。
或者,对于其他命令:
s/.*/$_ $new.mp4/'
:用原始名称 ($_
) 替换所有内容,后跟新名称。
答案2
已尝试并测试过。对于带空格的文件名也一样。
1)
find . -maxdepth 1 -name '*.mp4' -print0 | while read -d $'\0' i ;do
mv "$i" "`sha256sum "$i" | cut -d" " -f1`.mp4"
done
2)
find . -maxdepth 1 -name '*.mp4' -print0 | while read -d $'\0' i ;do
mv "$i" "${i%%.mp4}-`sha256sum "$i" | cut -d" " -f1`.mp4"
done
答案3
我只是想分享我的改进Vijay 的回答
如果您想使该过程递归(包括所有子目录),您可以使用以下命令:
find . -name '*.mp4' -print0 | while read -rd $'\0' i; do
mv -v "$i" "$(dirname "$i")/$(sha256sum "$i" | cut -d" " -f1).mp4"
done
答案4
这需要一个简单的 shell 循环:
for i in *.mp4 ; do
j="$(openssl dgst -sha256 \"$i\" | cut '-d ' -f2)"
mv "$i" "$j.mp4"
done
你的问题的第二部分需要做更多的工作:
for i in *.mp4 ; do
j="$(openssl dgst -sha256 \"$i\" | cut '-d ' -f2)"
k="${i%%.mp4}"
mv "$i" "$k_$j.mp4"
done