6

次のような名前の、数千のファイルを含むディレクトリがあります。

filename.ext
filename (1).ext
filename (2).ext
otherfile.ext
otherfile (1).ext
etc.

括弧で囲まれた番号が付いたファイルのほとんどは、元のファイルと重複していますが、そうでない場合もあります。

元のファイルを保持し、重複を削除し、異なるファイルを失わないようにするにはどうすればよいですか?

私はできることを知っていますがrm *\).ext、それは明らかにファイルが元のファイルと一致することを確認しません。

私はOSXを使用しているので、Linuxmd5のようmd5sumに機能するプログラムがありますが、ハッシュは行の先頭ではなく末尾に配置されます。awkスクリプトを使用して、の出力を取得し、md5 *.ext | awk 'some script'md5で重複を見つけて削除できると考えていましたが、コマンドラインが長すぎます(bash: /sbin/md5: Argument list too long)。

そして、私はスクリプトに何を書くべきかわかりません。私はこれで物事を配列に格納することを考えていました:

awk '{a[$NF]++} a[$NF]>1{sub(/).*/,""); sub(/.*(/,""); system("rm " $0);}'

しかし、それはいつも私のオリジナルを削除するようです。

私は何が間違っているのですか?どうすれば正しくできますか?

ありがとう。

4

2 に答える 2

6

.ファイルを並べ替えると、 (ピリオド) が(スペース) の後に並べ替えられるため、awk スクリプトは元のファイルを削除します。SO 表示された最初のファイルは、元のファイルではなく番号が付けられ、その後のチェック (元のファイルに対するものを含む) は、ファイルを最初の番号の付いたファイルと比較します。

オリジナルと一致しないだけでなくrm *\).txt、そもそもオリジナルを持たない可能性のあるファイルが失われます。

私はこれをこのようにはしません。すべての番号付きファイルをチェックしてオリジナルと一致するかどうかを確認するのではなく、オリジナルのリストを調べて、番号付きファイルと一致するものを削除できます。

その代わり:

$ for file in *[^\)].txt; do echo "-- Found: $file"; rm -v $(basename "$file" .txt)\ \(*\).txt; done

これを展開して、途中で MD5 を確認できます。しかし、それはより多くのコードであるため、スクリプトで複数の行に分割します。

#!/bin/bash

shopt -s nullglob              # Show nothing if a fileglob matches no files

for file in *[^\)].ext; do
  md5=$(md5 -q "$file")        # The -q option gives you only the message digest
  echo "-- Found: $file ($md5)"
  for duplicate in $(basename "$file" .ext)\ \(*\).ext; do
     if [[ "$md5" = "$(md5 -q "$duplicate")" ]]; then
        rm -v "$duplicate"
     fi
  done
done

別の方法として、MD5 ダイジェストを計算するよりも少ない CPU オーバーヘッドで、おそらくこれをもう少し簡単に行うことができます。Unix と Linux には というシェル ツールがcmpあり、これはdiff出力がないようなものです。そう:

#!/bin/bash

shopt -s nullglob

for file in *[^\)].ext; do
  for duplicate in $(basename "$file" .ext)\ \(*\).ext; do
    if cmp "$file" "$duplicate"; then
      rm -v "$file"
    fi
  done
done
于 2012-10-03T17:10:43.333 に答える
0

AWK を使用する必要がない場合は、bash でもっと簡単なことを行うことができます。

for file in *\([0-9]*\)*; do
    [ -e "$(echo "$file" | sed -e 's/ ([0-9]\+)//')" ] && rm "$file"
done

これが少し役立つことを願っています=)

于 2012-10-03T17:10:05.940 に答える