16

特定のディレクトリツリーで重複するファイル名をすべて見つける必要があります。ユーザーがスクリプトの引数としてどのディレクトリツリーを指定するかはわかりません。そのため、ディレクトリ階層がわかりません。私はこれを試しました:

#!/bin/sh
find -type f | while IFS= read vo
do
echo `basename "$vo"`
done

しかし、それは私が本当に欲しいものではありません。重複するファイル名がさらにある場合でも、重複を 1 つだけ見つけて終了します。パス全体 (ファイル名のみを出力) と重複カウントは出力しません。このコマンドに似た何かをしたかった:

find DIRNAME | tr '[A-Z]' '[a-z]' | sort | uniq -c | grep -v " 1 " 

しかし、それは私にとってはうまくいきません。理由はわかりません。重複があっても何も印刷されません。Xubuntu 12.04 を使用しています。

4

7 に答える 7

8
#!/bin/sh
dirname=/path/to/check
find $dirname -type f | 
while read vo
do
  echo `basename "$vo"`
done | awk '{arr[$0]++; next} END{for (i in arr){if(arr[i]>1){print i}}}  
于 2013-04-29T11:27:55.857 に答える
2
#!/bin/bash

file=`mktemp /tmp/duplicates.XXXXX` || { echo "Error creating tmp file"; exit 1; }
find $1 -type f |sort >  $file
awk -F/ '{print tolower($NF)}' $file |
        uniq -c|
        awk '$1>1 { sub(/^[[:space:]]+[[:digit:]]+[[:space:]]+/,""); print }'| 
        while read line;
                do grep -i "$line" $file;
        done

rm $file

また、ファイル名のスペースでも機能します。簡単なテストを次に示します (最初の引数はディレクトリです)。

./duplicates.sh ./test
./test/2/INC 255286
./test/INC 255286
于 2013-04-29T11:51:57.140 に答える
0

このソリューションは、見つかった一意のファイル名ごとに 1 つの一時ファイルを一時ディレクトリに書き込みます。後で出力できるように、一意のファイル名を最初に見つけたパスを一時ファイルに書き込みます。そのため、他の投稿されたソリューションよりも多くのファイルを作成します。でも、なんとなくわかる内容でした。

以下は、という名前のスクリプトfndupeです。

#!/bin/bash

# Create a temp directory to contain placeholder files.
tmp_dir=`mktemp -d`

# Get paths of files to test from standard input.
while read p; do
  fname=$(basename "$p")
  tmp_path=$tmp_dir/$fname
  if [[ -e $tmp_path ]]; then
    q=`cat "$tmp_path"`
    echo "duplicate: $p"
    echo "    first: $q"
  else
    echo $p > "$tmp_path" 
  fi
done

exit

以下は、スクリプトの使用例です。

$ find . -name '*.tif' | fndupe

以下は、スクリプトが重複したファイル名を検出した場合の出力例です。

duplicate: a/b/extra/gobble.tif
    first: a/b/gobble.tif

Bash バージョンでテスト済み:GNU bash, version 4.1.2(1)-release (x86_64-redhat-linux-gnu)

于 2015-08-05T22:32:52.573 に答える
0

これが私の貢献です(これは特定のファイルタイプ、この場合はpdfを検索するだけです)が、再帰的にそうします:

#!/usr/bin/env bash

find . -type f | while read filename; do
    filename=$(basename -- "$filename")
    extension="${filename##*.}"
    if [[ $extension == "pdf" ]]; then
        fileNameCount=`find . -iname "$filename" | wc -l`
        if [[ $fileNameCount -gt 1 ]]; then
            echo "File Name: $filename, count: $fileNameCount"
        fi
    fi
done
于 2019-03-11T17:08:36.547 に答える