我的 bash 脚本有什么问题?

我的 bash 脚本有什么问题?

应该做

根据当前目录中相同的 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

相关内容