如何批量删除“重复”文件?

如何批量删除“重复”文件?

我有很多重复的文件。这些文件看起来像这样:

dsc_0364_5723957929_o.jpg
dsc_0364_5294988157_o.jpg

dsc_0365_2464873748_o.jpg
dsc_0365_2853758327_o.jpg
....

我想删除具有相同前缀的第二个文件(有时是第三个)。我怎么做?

答案1

您可以gawkfindand一起使用xargs

find -maxdepth 1 -type f -name 'dsc*jpg' -print0 |
gawk 'BEGIN { RS=ORS="\0" ; FS="_" } seen[$2]++' |
xargs -0 rm

请注意,使用 NUL 作为记录分隔符是 AFAIK仅在 GNU awk 中受支持( gawk)。

答案2

如果所有文件都遵循相同的模式,则此解决方案有效:string_string_string_string.string.我的意思是文件名中必须有三个_才能获得其前缀。例如,有文件名:dsc_0360_5294988157_o.jpg我想获取它的前缀dsc_0360

以下脚本应该可以工作:

#! /usr/bin/env bash

lastPrefix=''

for i in ./* ; do
   prefix=${i%_*_*}
   if [[ $prefix == $lastPrefix ]];then
      rm $i
   else
      lastPrefix=$prefix
   fi
done

通过该行,prefix=${i%_*_*}我获取文件名的前缀,并比较之前是否已经设置了相同的前缀,如果是,则应该删除该文件。

您可能需要更改for i in ./* ;您的工作目录:for i in /path/to/your/working_directory ;

答案3

您将需要使用关联数组来跟踪您已经见过的文件名前缀。例如:

#!/bin/bash

# define $seen as an associative array (-A).
declare -A seen

for f in dsc_* ; do
  # derive a value for $prefix by removing the last
  # two _ sections from $f, e.g. remove '_5723957929_o.jpg'
  prefix=${f%_*_*}

  # test if "$seen"'s element for this "$prefix" is empty:
  if [ -z "${seen[$prefix]}" ] ; then
    # if it is, then we haven't seen this prefix before, so
    # we need to remember it.
    seen[$prefix]="$f"

    # optional debugging output. delete or comment out if
    # not needed.
    echo "seen[$prefix] = $f"

  else
    # Dry-run showing which files would be deleted.
    # remove the echo to actually delete it. Optionally
    # add -v for verbose output.
    echo rm -f "$f"
  fi
done

当在包含示例文件名的目录中运行时,它会生成以下输出:

seen[dsc_0364] = dsc_0364_5294988157_o.jpg
rm -f dsc_0364_5723957929_o.jpg
seen[dsc_0365] = dsc_0365_2464873748_o.jpg
rm -f dsc_0365_2853758327_o.jpg

如果它在没有调试输出的情况下运行并echo rm -f替换rm -fv为详细输出,则会产生以下输出

removed 'dsc_0364_5723957929_o.jpg'
removed 'dsc_0365_2853758327_o.jpg'

如果没有-v,它会删除文件但根本不产生任何输出。

相关内容