ファイル名の最初の数文字に基づいて重複ファイルを検索する

ファイル名の最初の数文字に基づいて重複ファイルを検索する

私はLinuxシェル(好ましくはbash)でファイル名の最初の数文字に基づいてファイルの重複を見つける方法を探しています。

これが便利な場合:

Minecraft用モードパックを製作しています。 1.14.4 以降、Forge はパッケージに冗長モードがあってもエラーは発生しません。最も古いバージョンの実行が停止します。これらの重複項目を見つけるのに役立つスクリプトは非常に便利です。

リストの例:

minecolonies-0.13.312-beta-universal.jar   
minecolonies-0.13.386-alpha-universal.jar 

詐欺を受けた人を迅速に特定することで、顧客基盤をより小さく保つことができます。

リクエストに応じて追加情報を提供

特定の形式はありません。しかし、ご覧のとおり、少なくとも2つの一般的な形式があります。さらに、コミュニティにはどのキャラクターを使用するか、使用しないかについての標準はありません。一部は空白(より嫌がらせ)を使用し、一部は[](さらに嫌がらせ)を使用し、一部は_(より嫌がらせ)を使用し、一部は-(優先されますが何ができるか)を使用します。

https://gist.github.com/be3cc9a77150194476b2000cb8ee16e5サンプルモードファイル名のリストです。きれいに掃除されており、破れたものは一つもありません。

https://gist.github.com/b0ac1e03145e893e880da45cf08ebd7a私が意図的にコピーしたサンプルが含まれています。これは時々起こる誇張された仕事です。

より詳細な説明

私はこれがリソース集約的かもしれないことを知っています。

サンプリングするすべてのファイル名の先頭から最後まで、スライス範囲をランダムに指定したいと思います。そのフラグメントに基づいて重複項目を検索し、重複項目を強調表示します。実際に削除するスクリプトは必要ありません。

追加クレジット

スクリプトは、簡単に削除したり名前を変更したりできるように、コピー基準を満たすと疑われるファイルのメニューを表示します。

答え1

冗長性のフィルタリング

一部のスクリプトを使用して、重複する可能性のあるファイルをフィルタリングできます。名前の最初のダッシュ、アンダースコア、またはスペースの前にある1つ以上の他のファイルと一致するすべてのファイル(大文字と小文字を区別しない)を新しいディレクトリに移動できます。cdjarsディレクトリに移動して実行します。

#!/bin/bash
mkdir -p possible_dups

awk -F'[-_ ]' '
    NR==FNR {seen[tolower($1)]++; next}
    seen[tolower($1)] > 1
' <(printf "%s\n" *.jar) <(printf "%s\n" *.jar) |\
    xargs -r -d'\n' mv -t possible_dups/ --

注:可能な重複エントリが見つからないときにファイル引数なしで一度実行されるのを-r防ぐためのGNU拡張です。mvまた、GNU 引数は-d'\n'ファイル名を改行で区切ります。つまり、上記のコマンドでは、スペースやその他の一般文字は処理されますが、改行は処理されません。

フィールド区切り文字の割り当てを編集して、文字を追加または削除して-F'[-_ ]'繰り返しをテストするセクションの終わりを定義できます。今は「突進、解く、または空白」を意味します。一般的に言えば、ここで行ったように、繰り返しのケースについて実際よりも多くのデータをキャプチャすることをお勧めします。

これで、これらのファイルを確認できます。ファイル数がそれほど多くないと思われる場合は、フィルタリングなしですべてのファイルに対して次の手順を実行することもできます。


冗長性に関する目視検査

これにはビジュアルシェルを使用することをお勧めしますmc真夜中司令官mcLinuxディストリビューションのパッケージ管理ツールを使用して簡単にインストールできます。

mcこれらのファイルを含むディレクトリを呼び出すか、そのディレクトリに移動できます。 X端末を使用するとマウスもサポートされますが、すべての操作に便利なショートカットがあります。

たとえば、メニューには、目的のソートされたLeft -> Sorting... -> untick "case sensitive"ビューが表示されます。

矢印を使用してファイルを参照して複数のファイルを選択し、強調表示された選択Insert項目をコピー(F5)、移動(F6)、または削除(F8)できます。以下は、フィルタリングされたテストデータのスクリーンショットです。

ここに画像の説明を入力してください。

答え2

私たちには解決策があります。 MCやRangerなどのシェルマネージャを使用しなくても、bashドライバという目標を簡単に達成できるため、この回答を受け入れました。

#!/bin/bash

declare -a names

xIFS="${IFS}"
IFS="^M"

while true; do
awk -F'[-_ ]' '
    NR==FNR {seen[tolower($1)]++; next}
    seen[tolower($1)] > 1
' <(printf "%s\n" *.jar) <(printf "%s\n" *.jar) > tmp.dat

        IDX=0
        names=()


        readarray names < tmp.dat

        size=${#names[@]}

        clear
        printf '\nPossible Dupes\n'

        for (( i=0; i<${size}; i++)); do
                printf '%s\t%s' ${i} ${names[i]}
        done

        printf '\nWhich dupe would you like to delete?\nEnter # to delete or q to quit\n'
        read n

        if [ $n == 'q' ]; then
                exit
        fi

        if [ $n -lt 0 ] || [ $n -gt $size ]; then
                read -p "Invalid Option: present [ENTER] to try again" dummyvar
                continue
        fi

        #clean the carriage return \n from the name
        IFS='^M'
        read -ra TARGET <<< "${names[$n]}"
        unset IFS

        # now remove the filename sans any carriage returns
        # from the filesystem
        # 12/18/2020
        rm "${TARGET[*]}" 
        echo "removed ${TARGET[0]}" >> rm.log
done

IFS="${xIFS}"

結果に満足するまで、重複とループを見つけるために何百ものファイル名を読む必要がないので、これは私にとってうまくいきます。また、私のタスクをログファイルに保存します。

通常、冗長モードはほとんど発生しませんが、冗長モードが発生すると問題になります。このスクリプトは私の状況を大幅に改善しました。

スクリプトをよりインテリジェントでユーザーフレンドリーにすることができれば、ぜひ見たいと思います。

編集者:2020年11月5日

  • 私の心を変えた
  • このスクリプトを数日間使用してきたのはとても便利でした。
  • 私ができることは、クライアントパッケージをアップグレードし、クライアントモードを除くすべてのアイテムをサーバーにアップロードしてから、このスクリプトを使用してサーバーモード/フォルダをすばやく整理することです。これでパッケージメンテナンスが速くなりました!
  • IFSを使用してメニューから出力をクリーンアップするようにスクリプトが更新されました。

修正日:2020年12月18日

  • わずかに変更すると、より多くの状況でスクリプトが正しく機能する可能性があります。

関連情報