「重複」ファイルを一括削除する方法は?

「重複」ファイルを一括削除する方法は?

重複したファイルがたくさんあります。ファイルは次のようになります。

dsc_0364_5723957929_o.jpg
dsc_0364_5294988157_o.jpg

dsc_0365_2464873748_o.jpg
dsc_0365_2853758327_o.jpg
....

同じプレフィックスを持つ2番目(時には3番目)のファイルを削除したいと思います。どうすればいいですか?

答え1

以下でgawk使用できます。findxargs

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ファイル名に3つが必要です。_たとえば、dsc_0360_5294988157_o.jpgファイル名があります。 I want to get its prefix 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ファイルを削除しますが、まったく出力を生成しません。

関連情報