将文件重命名为哈希和扩展名
Rename files to hash and extension
问题的回答 here 符合 OP 的喜好,但我无法让它 100% 为我工作。我想要做的是在 /home/hermit/Documents/Pictures
中获取文件并在将新文件放入 /home/hermit/Documents/HashPictures
之前对其进行哈希处理,同时将文件保留在 /home/hermit/Documents/
中。不幸的是,解决方案似乎不适用于 GIF 和 JPG。
Or GNU sed can do it even shorter:
# md5sum * | sed -e 's/\([^ ]*\) \(.*\(\..*\)\)$/mv -v /e'
另一件好事是,如果我能有一个易于阅读的脚本或脚本的解释。
编辑:这些是剩余的文件(在/home/hermit/Documents/Pictures
和终端输出中。剩余的文件:File names inside
hermit@hermit:~/Documents/PicturesHashed$ ./hash.sh
mv: target '9c48b6846aa3211ba867d9775aa9a730.jpg' is not a directory
mv: target '6cef7445eb7382aa719e364dc2d0126c.jpg' is not a directory
mv: target 'b3624eae0010f7d042af838859d5ea0e.png' is not a directory
mv: target '12f8f700cc73abe05da61103184f2ed0.jpg' is not a directory
mv: target '340e018ba57016f469a1039fb19c2619.jpg' is not a directory
mv: target '89da545ea3084500cd86a6265676173c.jpg' is not a directory
mv: target '7ff0671fc0447ca009d216670a0e2ac9.gif' is not a directory
mv: target '300d7e1e9807701f1a5043de85992484.jpg' is not a directory
mv: target 'c340521eec897957c0a7d6f415232ae4.png' is not a directory
mv: target '263ef6fd0b8623227a705bbcecb61755.gif' is not a directory
mv: target '2f4e522461ff467d5b4a09b7d33c2114.jpg' is not a directory
mv: target '2372edeb385381540d2230266ad5a4d2.png' is not a directory
mv: target 'bf5fc13be51d281347e0b00694c7689b.jpg' is not a directory
mv: target '3ab04030a8d06ff5aa5dca406c3927b0.jpg' is not a directory
mv: target '84d61abe2ff50e81d96e9b5ca916048e.jpg' is not a directory
mv: target 'c1c74496d880e4a20403c65e583dff54.jpg' is not a directory
mv: target '99c2a10e1f4ce27a08eafb70cbac09c1.jpg' is not a directory
mv: target '7ff0671fc0447ca009d216670a0e2ac9.gif' is not a directory
mv: target 'e27c3fe527a6417e13f2b55865b77d4f.jpg' is not a directory
mv: target 'd32b6aa0ff3929b477fe5e33872220d1.png' is not a directory
mv: target '70df8a56449a7b19b286e0b77394a7c8.jpg' is not a directory
mv: target '7e9b7446ea3fe662fa7ba3ba45952cbf.jpg' is not a directory
mv: target '975de97e64c345cbe41532101636c70e.gif' is not a directory
mv: target 'c3a691daa3400f00c87de37703ddd222.jpg' is not a directory
sh: 1: Syntax error: "(" unexpected
sh: 1: Syntax error: "(" unexpected
mv: target 'ce14ef4371c5fe6a61a539a9f22e6227.jpg' is not a directory
我觉得这更容易阅读和遵循:
#!/bin/bash
source_dir=/home/hermit/Documents/Pictures
destination_dir=/home/hermit/Documents/HashPictures
for file in "${source_dir}"/*;do
hash=$(md5sum "${file}"|cut -d' ' -f1)
ext=${file##*.}
cp -v "$file" "${destination_dir}/${hash}.${ext}"
done
Perl 来拯救:
#!/usr/bin/perl
use warnings;
use strict;
use Digest::MD5 qw{ md5_hex };
my ($source, $target) = @ARGV;
$source =~ s/(\s)/\/g;
for my $file (glob "$source/*") {
open my $fh, '<', $file or die "$file: $!";
my $content = do { local $/; <$fh> };
my $digest = md5_hex($content);
my ($extension) = $file =~ /\.([^.]*)/;
open my $out, '>', "$target/$digest.$extension" or die "$file: $!";
print {$out} $content;
close $out;
}
运行 作为
perl script-name -- "source-dir" "target-dir"
A 部分 - 您所见
Or GNU sed can do it even shorter:
# md5sum * | sed -e 's/\([^ ]*\) \(.*\(\..*\)\)$/mv -v /e'
我个人不喜欢在这些情况下使用 sed
,如果让我在专业代码中审查它,我会拒绝它,因为它对未来的读者来说太难理解了。
Sed 是一个流编辑器。您将内容输入其中对其进行编辑,然后推出结果。它使用 regular expressions 来匹配其输入的模式,然后对其进行处理。正则表达式很难阅读,即使您已经使用了一段时间,所以我不希望有很多人能够阅读上面的代码。人们倾向于使用它,因为它可以用很少的代码做很多事情。
Sed 有很多派对技巧,在本例中它被用来执行其他命令 (mv
)。
md5sum *
产生这样的输出:
263620ac1a08b934b5312f416fe7a1af IMAG0001.jpg
972eddbf8e368a9c3d38e66bcf924cbc IMAG0002.jpg
94b30dfedb8afb7143268d1c329d7e64 IMAG0004.jpg
c592b83172e7f3c2d20207ee4e0cdd0d IMAG0005.jpg
1bc861c1251d87aea5e98ff263e09e79 IMAG0223.jpg
560afa8d60ff833a9dee52eff2fc420b IMAG0224.jpg
Sed 然后将其编辑为如下所示:
mv -v IMAG0001.jpg 263620ac1a08b934b5312f416fe7a1af.jpg
mv -v IMAG0002.jpg 972eddbf8e368a9c3d38e66bcf924cbc.jpg
mv -v IMAG0004.jpg 94b30dfedb8afb7143268d1c329d7e64.jpg
mv -v IMAG0005.jpg c592b83172e7f3c2d20207ee4e0cdd0d.jpg
mv -v IMAG0223.jpg 1bc861c1251d87aea5e98ff263e09e79.jpg
mv -v IMAG0224.jpg 560afa8d60ff833a9dee52eff2fc420b.jpg
Sed 然后执行这段代码。
现在您明白了,您很可能可以挑选出 mv -v
并将其换成 cp
或其他命令。但是您仍然会遇到 space 和特殊字符的问题。
B 部分 - 更强大的解决方案
我会完全避免 sed
。如果您不了解它,请不要使用它。大多数人不明白。
for file in *.jpg
do
sum=`md5sum "$file"`
#remove the file name from md5sum's output
# this is using bash's pattern matching but can be swapped out
sum="${sum% $file}"
cp "$file" "HashPictures/$sum"
done
请注意,我在 $file
和 $sum
两边都加上了引号。此外,我们每个命令处理一个文件,而不是每个文件一个命令。这样,文件名中的 space 永远不会与用于拆分命令参数的 space 混淆。
C 部分 - 最后的想法
对于此示例代码,我使用 cp
将图像的副本放在新目录中。那可能不是你想要的。例如使用 ln -s "$file" "HashPictures/$sum"
来创建 symbolic link。这将避免需要复制文件并节省大量 space.
这是一个 Python 解决方案。将其放入要转换的同一目录中的 Python 文件中(或修改 '.'
)。
import hashlib
import os
def file_as_bytes(file):
with file:
return file.read()
def hash_file(fpath):
return hashlib.md5(file_as_bytes(open(fpath, 'rb'))).hexdigest()
for fname in os.listdir('.'):
name, ext = os.path.splitext(fname)
hash = hash_file(fname)
dst = hash + ext
print(fname + " --> " + dst)
os.rename(fname, dst)
将当前目录中所有非目录的文件重命名为
md5sum * | awk '{print "mv", , ".jpg" }' | bash
或
md5sum -- * | awk '{print "mv --", , ".jpg" }' | bash
如果文件以缺点开头。
问题的回答 here 符合 OP 的喜好,但我无法让它 100% 为我工作。我想要做的是在 /home/hermit/Documents/Pictures
中获取文件并在将新文件放入 /home/hermit/Documents/HashPictures
之前对其进行哈希处理,同时将文件保留在 /home/hermit/Documents/
中。不幸的是,解决方案似乎不适用于 GIF 和 JPG。
Or GNU sed can do it even shorter:
# md5sum * | sed -e 's/\([^ ]*\) \(.*\(\..*\)\)$/mv -v /e'
另一件好事是,如果我能有一个易于阅读的脚本或脚本的解释。
编辑:这些是剩余的文件(在/home/hermit/Documents/Pictures
和终端输出中。剩余的文件:File names inside
hermit@hermit:~/Documents/PicturesHashed$ ./hash.sh
mv: target '9c48b6846aa3211ba867d9775aa9a730.jpg' is not a directory
mv: target '6cef7445eb7382aa719e364dc2d0126c.jpg' is not a directory
mv: target 'b3624eae0010f7d042af838859d5ea0e.png' is not a directory
mv: target '12f8f700cc73abe05da61103184f2ed0.jpg' is not a directory
mv: target '340e018ba57016f469a1039fb19c2619.jpg' is not a directory
mv: target '89da545ea3084500cd86a6265676173c.jpg' is not a directory
mv: target '7ff0671fc0447ca009d216670a0e2ac9.gif' is not a directory
mv: target '300d7e1e9807701f1a5043de85992484.jpg' is not a directory
mv: target 'c340521eec897957c0a7d6f415232ae4.png' is not a directory
mv: target '263ef6fd0b8623227a705bbcecb61755.gif' is not a directory
mv: target '2f4e522461ff467d5b4a09b7d33c2114.jpg' is not a directory
mv: target '2372edeb385381540d2230266ad5a4d2.png' is not a directory
mv: target 'bf5fc13be51d281347e0b00694c7689b.jpg' is not a directory
mv: target '3ab04030a8d06ff5aa5dca406c3927b0.jpg' is not a directory
mv: target '84d61abe2ff50e81d96e9b5ca916048e.jpg' is not a directory
mv: target 'c1c74496d880e4a20403c65e583dff54.jpg' is not a directory
mv: target '99c2a10e1f4ce27a08eafb70cbac09c1.jpg' is not a directory
mv: target '7ff0671fc0447ca009d216670a0e2ac9.gif' is not a directory
mv: target 'e27c3fe527a6417e13f2b55865b77d4f.jpg' is not a directory
mv: target 'd32b6aa0ff3929b477fe5e33872220d1.png' is not a directory
mv: target '70df8a56449a7b19b286e0b77394a7c8.jpg' is not a directory
mv: target '7e9b7446ea3fe662fa7ba3ba45952cbf.jpg' is not a directory
mv: target '975de97e64c345cbe41532101636c70e.gif' is not a directory
mv: target 'c3a691daa3400f00c87de37703ddd222.jpg' is not a directory
sh: 1: Syntax error: "(" unexpected
sh: 1: Syntax error: "(" unexpected
mv: target 'ce14ef4371c5fe6a61a539a9f22e6227.jpg' is not a directory
我觉得这更容易阅读和遵循:
#!/bin/bash
source_dir=/home/hermit/Documents/Pictures
destination_dir=/home/hermit/Documents/HashPictures
for file in "${source_dir}"/*;do
hash=$(md5sum "${file}"|cut -d' ' -f1)
ext=${file##*.}
cp -v "$file" "${destination_dir}/${hash}.${ext}"
done
Perl 来拯救:
#!/usr/bin/perl
use warnings;
use strict;
use Digest::MD5 qw{ md5_hex };
my ($source, $target) = @ARGV;
$source =~ s/(\s)/\/g;
for my $file (glob "$source/*") {
open my $fh, '<', $file or die "$file: $!";
my $content = do { local $/; <$fh> };
my $digest = md5_hex($content);
my ($extension) = $file =~ /\.([^.]*)/;
open my $out, '>', "$target/$digest.$extension" or die "$file: $!";
print {$out} $content;
close $out;
}
运行 作为
perl script-name -- "source-dir" "target-dir"
A 部分 - 您所见
Or GNU sed can do it even shorter:
# md5sum * | sed -e 's/\([^ ]*\) \(.*\(\..*\)\)$/mv -v /e'
我个人不喜欢在这些情况下使用 sed
,如果让我在专业代码中审查它,我会拒绝它,因为它对未来的读者来说太难理解了。
Sed 是一个流编辑器。您将内容输入其中对其进行编辑,然后推出结果。它使用 regular expressions 来匹配其输入的模式,然后对其进行处理。正则表达式很难阅读,即使您已经使用了一段时间,所以我不希望有很多人能够阅读上面的代码。人们倾向于使用它,因为它可以用很少的代码做很多事情。
Sed 有很多派对技巧,在本例中它被用来执行其他命令 (mv
)。
md5sum *
产生这样的输出:
263620ac1a08b934b5312f416fe7a1af IMAG0001.jpg
972eddbf8e368a9c3d38e66bcf924cbc IMAG0002.jpg
94b30dfedb8afb7143268d1c329d7e64 IMAG0004.jpg
c592b83172e7f3c2d20207ee4e0cdd0d IMAG0005.jpg
1bc861c1251d87aea5e98ff263e09e79 IMAG0223.jpg
560afa8d60ff833a9dee52eff2fc420b IMAG0224.jpg
Sed 然后将其编辑为如下所示:
mv -v IMAG0001.jpg 263620ac1a08b934b5312f416fe7a1af.jpg
mv -v IMAG0002.jpg 972eddbf8e368a9c3d38e66bcf924cbc.jpg
mv -v IMAG0004.jpg 94b30dfedb8afb7143268d1c329d7e64.jpg
mv -v IMAG0005.jpg c592b83172e7f3c2d20207ee4e0cdd0d.jpg
mv -v IMAG0223.jpg 1bc861c1251d87aea5e98ff263e09e79.jpg
mv -v IMAG0224.jpg 560afa8d60ff833a9dee52eff2fc420b.jpg
Sed 然后执行这段代码。
现在您明白了,您很可能可以挑选出 mv -v
并将其换成 cp
或其他命令。但是您仍然会遇到 space 和特殊字符的问题。
B 部分 - 更强大的解决方案
我会完全避免 sed
。如果您不了解它,请不要使用它。大多数人不明白。
for file in *.jpg
do
sum=`md5sum "$file"`
#remove the file name from md5sum's output
# this is using bash's pattern matching but can be swapped out
sum="${sum% $file}"
cp "$file" "HashPictures/$sum"
done
请注意,我在 $file
和 $sum
两边都加上了引号。此外,我们每个命令处理一个文件,而不是每个文件一个命令。这样,文件名中的 space 永远不会与用于拆分命令参数的 space 混淆。
C 部分 - 最后的想法
对于此示例代码,我使用 cp
将图像的副本放在新目录中。那可能不是你想要的。例如使用 ln -s "$file" "HashPictures/$sum"
来创建 symbolic link。这将避免需要复制文件并节省大量 space.
这是一个 Python 解决方案。将其放入要转换的同一目录中的 Python 文件中(或修改 '.'
)。
import hashlib
import os
def file_as_bytes(file):
with file:
return file.read()
def hash_file(fpath):
return hashlib.md5(file_as_bytes(open(fpath, 'rb'))).hexdigest()
for fname in os.listdir('.'):
name, ext = os.path.splitext(fname)
hash = hash_file(fname)
dst = hash + ext
print(fname + " --> " + dst)
os.rename(fname, dst)
将当前目录中所有非目录的文件重命名为
md5sum * | awk '{print "mv", , ".jpg" }' | bash
或
md5sum -- * | awk '{print "mv --", , ".jpg" }' | bash
如果文件以缺点开头。