linux - BASH-查找相同大小的文件,使用 cksum,删除 dupe 但保留其名称作为符号链接(symbolic link)

标签 linux bash unix scripting automation

祝你有美好的一天!我是一名实习生,刚刚开始学习 bash 脚本(感谢 bash.academy!),并正在尝试创建一个执行以下操作的脚本;

  1. 查找相同大小的文件
  2. 通过 cksum 确定文件内容是否重复
  3. 删除重复文件,保留两个文件名,将删除的文件转换为剩余文件的符号链接(symbolic link)。

正在发生的事情的背景;有一个程序可以生成这些文件,并且它会大量生成重复项。它创建了一对包含完全相同的数据但名称不同的文件,并且我们有依赖重复文件的程序(同样,我们无法更改这些程序来检查非重复文件),因此我必须将已删除的文件转换为符号链接(symbolic link)。我很感激任何建议,干杯!

`e#!/usr/bin/env bash
cd /path/to/files
ls -l -S | sort -k 5 -n #sort file sizes in revers order
cksum /path/to/files/* |        #File duplication verification
  awk ' { if( $2 in arr) 
            {print "duplicates ", $3, arr[$2], "duplicate filesize = ", $2} 
              else 
            {arr[$2]=$3} }' 
`

最佳答案

虽然问题不是很清楚,但我希望下面的脚本有所帮助:

#!/bin/bash
# Removing the duplicate files based on md5 hash based asscociative arrays
declare -A file_list # Note -A is for associative array
# The above associate array will have the below format
# file_list=([md5-hash]=filename)
duplicate_remover()
{
 md5_data=( $(md5sum "$1") )
 # md5sum gives the output in 'hash filename' format. See Reference 1
 check_exist=${file_list["X${md5_data[0]}"]+exists}
 # Above command check if the array element with the given key already exists in 'file_list' array.
 # We have used shell parameter expansion. See Reference 2
 if [ "$check_exist" = "exists" ]
 then
   ln -fs "${file_list["X${md5_data[0]}"]}" "$1"
   # Above steps turns duplicates to symbolic links. 
   # Note the '-f' with 'ln' forces rewrite if dest. file is already present
 else
   file_list+=(["X${md5_data[0]}"]="$1")
   # If the file is not already in the array, we add it using [key]=value construct.
 fi
}
#Our driver part below uses 'find' command to feed files into 'duplicate_remover' function
find . -maxdepth 1 -type f -print0 | while read -r -d '' filename
do
   duplicate_remover "$filename"
done

引用文献

  1. 参见md5sum manpage .
  2. 查看 shell 中 ${var+stuff} 的用法 parameter expansion .

注释

  1. 我假设所有文件都存在于同一目录中,如果没有从 find 中取出 -maxdepth 1
  2. 首先使用 find 出现的文件将被保留,其余文件将转换为链接。

关于linux - BASH-查找相同大小的文件,使用 cksum,删除 dupe 但保留其名称作为符号链接(symbolic link),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38060741/

相关文章:

java - 什么不适用于 ProcessBuilder 和 Daemons

c++ - 多线程 curl 请求的段错误

c++ - 如何在 C++ 中使用 cin 隐藏用户输入?

linux - 用 Awk 洗牌

bash - 在 bash 脚本中保持 SSH 打开

c++ - 运行 UNIX 应用程序的堆栈跟踪

java - 从 java 运行 python 脚本产生 KeyError

php - 使用 PHP 从字符串中转义所有特殊字符

android - "adb pull"在 Bash 脚本中返回空文件

c - 用C程序查找HP-UX上的进程使用的虚拟内存?