![我的 bash 脚本有什么问题?](https://linux22.com/image/1091000/%E6%88%91%E7%9A%84%20bash%20%E8%84%9A%E6%9C%AC%E6%9C%89%E4%BB%80%E4%B9%88%E9%97%AE%E9%A2%98%EF%BC%9F.png)
应该做:
根据当前目录中相同的 md5sum 列出每行重复的文件名
首先安装环境:
echo "hello" > file1; cp file1 file2; cp file2 file3;
Shell 脚本:
#!/bin/bash
#FileName: ls_duplicate.sh
## ls file in size-desc order and long listing format and long-iso timestyle
## -rw-rw-r-- 1 ubuntu ubuntu 6 2017-11-21 13:58 file1
## -rw-rw-r-- 1 ubuntu ubuntu 6 2017-11-21 13:58 file2
## -rw-rw-r-- 1 ubuntu ubuntu 5 2017-11-21 13:58 output
find -maxdepth 1 -type f -exec basename {} \; | xargs ls -lS --time-style=long-iso | awk 'BEGIN {
getline;getline;
prev_name=$8; prev_size=$5;
}
{
cur_name=$8;
cur_size=$5;
if (prev_size==cur_size)
{
"md5sum " prev_name | getline;
prev_md5_sum=$1;
"md5sum " cur_name | getline;
cur_md5_sum=$1;
# print(prev_name, prev_md5_sum, cur_name, cur_md5_sum); # debug
##if the two file is same size and same md5sum, then print duplicate file-name
if ( prev_md5_sum==cur_md5_sum ) { print prev_name; print cur_name;}
}
prev_size=cur_size; prev_name=cur_name;
}' | sort -u
当前目录中的文件:
file1 file2 file3 ls_duplicate.sh
运行脚本:
./ls_duplicate.sh
输出:
file1 b1946ac92492d2347c6235b4d2611184 file2 b1946ac92492d2347c6235b4d2611184
file2 -rw-rw-r-- file3 b1946ac92492d2347c6235b4d2611184
那么这里发生了什么-rw-rw-r--
?
解决方案
好吧,我自己解决了这个问题,而不是使用
"md5sum " prev_name | getline;
prev_md5_sum=$1;
"md5sum " cur_name | getline;
cur_md5_sum=$1;
而是使用
"md5sum " prev_name | getline md5_sum;
split(md5_sum, arr, " ");
prev_md5_sum=arr[1];
"md5sum " cur_name | getline md5_sum;
split(md5_sum, arr, " ");
cur_md5_sum=arr[1];
笔记:你需要在脚本中更改此内容(原始脚本做过不行)。
答案1
看起来你:
- 获取文件列表
- 然后它们的大小等等
- 然后生成相同大小的文件的 md5sum
- 并打印出具有相同 md5sum 的
我不会尝试修复 awk 代码。相反,请注意,您正在复制该fdupes
命令的功能。来自手册页:
Searches the given path for duplicate files. Such files are found by
comparing file sizes and MD5 signatures, followed by a byte-by-byte
comparison.
我强烈建议您使用它,而不是为此编写复杂的脚本。
如果不这样做,消除大小检查可以更容易地找到重复项:
$ md5sum * | sort -k1,1 | uniq -w32 -D
b1946ac92492d2347c6235b4d2611184 file1
b1946ac92492d2347c6235b4d2611184 file2
b1946ac92492d2347c6235b4d2611184 file3
所有哈希值md5sums
的宽度均为 32 个字符,因此很容易告诉打印uniq
仅比较这 32 个字符并打印找到的所有重复项。
如果您绝对必须进行尺寸检查,那么它会变得相当复杂,但仍然比您的脚本简单。find
可以打印文件大小,因此无需ls
混合使用:
find . -maxdepth 1 -type f -printf "%s/%P\n" |
awk -F/ ' # Use / as delimiter, it wont appear in filename
s[$1]++ { # if the file size has appeared before
if (n[$1]) { # if the first name hasnt been printed yet
print n[$1] # print it and delete it
n[$1] = "";
}
print $2; # print filename with duplicated size
next
} {n[$1] = $2} # save filename for each new size encountered'
这个 awk 命令将打印所有大小重复的文件。
现在,只需使用md5sum | sort | uniq
前面提到的管道:
find -maxdepth 1 -type f -printf "%s/%P\n" |
awk -F/ 's[$1]++ {if (n[$1]){print n[$1]} print $2; n[$1] = ""; next} {n[$1] = $2}' |
xargs -d '\n' md5sum |
sort -k1,1 |
uniq -w32 -D