ファイル名が若干異なる重複ファイルを探す

ファイル名が若干異なる重複ファイルを探す

bashスクリプトまたはコマンドを使用して角かっこ内でのみ異なりますが、非常に似た名前のファイルを見つけたいと思います。例えば

Filename (year1)
Filename (year2)

一致する必要があります。

または、より具体的に言えば、

Filename (2000)
Filename (2001)

一致する必要があります。

答え1

次のスクリプトは、位置引数のリストをパターンに一致する名前のリスト*' ('*')'、つまり名前にスペースがあり、最後に括弧がある現在のディレクトリ内のすべてのファイルに設定することによって機能します。

スクリプトはダブルループを使用して、各名前を他のすべての名前と比較します。A名前を他の名前と比較してBからと比較するBことを避けるために、A外部反復が開始されたときにリストの最初の要素を移動します。これにより、A名前自体のテストも防止されます。

内部ループでは、名前の末尾の角かっこを削除し、2つの結果文字列を比較します。文字列が同じ場合は名前を印刷します。

#!/bin/sh

set -- *' ('*')'

for name do
        shift

        for dup do
                if [ "${name%% (*)}" = "${dup%% (*)}" ]; then
                        printf '"%s" <-> "%s"\n' "$name" "$dup"
                fi
        done
done

答え2

遅くなりましたが、Gawkを使用してファイル名を処理する小さなBashスクリプトを書く必要があると思いました。特定のディレクトリにあるファイル間のさまざまななりすましにフラグを付けます。ファイルペアを一度だけ確認しても、処理はまだO(n ^ 2)です。

興味のあるディレクトリ(たとえば、次を含むディレクトリ)でスクリプトを実行します。

$ \ls -A -1
2323- (1236).suffix
23232(1234).suffix
23232 (1236).hsj
23232 (1236).suffix
hello(2001.10.29)fgh.ssh
hello(2002.10.29)fgh.ssh
23232(1236).suffix
23232(12 6).suffix
23232 (1286).suffix
23232 (1446).suffix
23232(3236).suffix
dwlkl(1234).sds

現在のスクリプト:

$ cat near_match.sh
#!/usr/bin/env bash
gawk '
    {i++; a[i] = $0; next}  # put files to check in array 'a'
    END {
        nfiles = i; # number of files to check
        for (i = 1; i <= nfiles-1; i++) {
            lblkarr1 = split(a[i], blkarr1, "[()]");
            lparr1 = split(blkarr1[2], parr1, "");
            for (j = i+1; j <= nfiles; j++) {
                lblkarr2 = split(a[j], blkarr2, "[()]");
                lparr2 = split(blkarr2[2], parr2, "");
                mismatch = 0;
                if ("x"blkarr1[1]"x" == "x"blkarr2[1]"x" && "x"blkarr1[3]"x" == "x"blkarr2[3]"x" && lparr1 == lparr2) {
                    for (k=1; k<=length(blkarr1[2]); k++) { if (parr1[k] != parr2[k]) mismatch++ };
                    if (mismatch == 1)  printf "dupes: %s  <-->  %s\n", a[i], a[j];
                }
            }
        }
    }' <<< $(\ls -A -1 -- *"("*")"*)

exit 0

スクリプトを実行可能にし、引数なしで実行します。

$ near_match.sh
dupes: 23232(1234).suffix  <-->  23232(1236).suffix
dupes: 23232 (1236).suffix  <-->  23232 (1286).suffix
dupes: hello(2001.10.29)fgh.ssh  <-->  hello(2002.10.29)fgh.ssh
dupes: 23232(1236).suffix  <-->  23232(12 6).suffix
dupes: 23232(1236).suffix  <-->  23232(3236).suffix
  • OPが指定したように、「dupe」は角括弧内の1文字の不一致として具体的に定義されます。ファイル名のどこでも文字の不一致を検出できるようにソリューションを拡張してソリューションを調整することは容易ではありません。
  • 角かっこはファイル名の任意の場所に置くことができ、ファイル名にサフィックスが含まれている場合と存在しない場合があります。
  • 提案された解決策は、ファイル名の特殊文字(追加の角かっこを除く)にとって強力なようです。
  • 最小限の変更で、1文字の不一致を複数の文字の不一致に変更できます。スクリプトにパラメータを入力してこの番号を変更するのは簡単です。必要かどうか尋ねてください。

ファタイ

関連情報