2017-08-01 3 views
-2

ディレクトリから重複ファイルを取得するにはどうすればよいですか?私はファイルのバージョン番号を無視したい。シェル内のディレクトリから重複ファイルを取得する

directory 
    httpcore-4.3.jar 
    httpcore.jar 
    http.jar 

私はhttpcoreをお返しします。 私は考えることができる最も簡単な方法は、

allfiles <-- readAllFileNames() 
for file1 in allfiles 
    for file2 in allfiles 
     compare file1 and file2 by ignoring version 

は、いずれかが別の効率的な方法がありますか?

+1

"重複"を "名前からバージョン番号を削除した場合、同じ名前になる複数のファイル"と定義していますか?どのようにバージョン番号を定義していますか?バージョンナンバリングスキームがたくさんあり、 '4.3'のために働くものは必ずしも' 4.3.1'や '4.3rc1'などを捕まえるものではありません。 –

+0

名前からバージョン番号を削除した場合、同じ名前になりますか? " →はい。私はあなたが言及したかなり標準バージョン番号を扱っています。 – sattu

+0

各ファイルのチェックサムを一度生成する - 重複するチェックサムを見つける。 –

答えて

0

バージョン番号と一致する正規表現を定義することができる場合は、seduniqでこのような何かを行うことができます。

ls | sed -r 's/(v?-[[:digit:]].*)?\.[[:alpha:]]+$//' | uniq --repeated 

この特定の正規表現はハイフンは数字が続くものと一致したが(それだと仮定するとバージョン番号の開始)、いずれの場合もファイル拡張子と一致し、それらを削除します。

  • -r:使用すると、それが簡単に凝ったの 一部を使用するために作る正規表現を、拡張ここ

    $ ls -Fl 
    total 0 
    -rw-rw-r--. 1 dhouck dhouck 0 Aug 2 10:28 httpcore-4.3.jar 
    -rw-rw-r--. 1 dhouck dhouck 0 Aug 2 10:28 httpcore.jar 
    -rw-rw-r--. 1 dhouck dhouck 0 Aug 2 10:28 http.jar 
    $ ls | sed -r 's/(v?-[[:digit:]].*)?\.[[:alpha:]]+$//' | uniq --repeated 
    httpcore 
    

    sedコマンドは、あなたがそれを変更したい場合には、具体的に、何をするかです以下。

  • s/ ... / ... /:「代替」コマンドを開始してください。最初のスラッシュと2番目のスラッシュの間のすべてを正規表現として取り出し、2番目と3番目のスラッシュの間に置き換えます。この場合、2番目と3番目のスラッシュの間には何もないので、一致したものを取り除くだけです。
  • ( ... )?:かっこでグループ化することで、それらの間のすべてが1つの単位として扱われます。疑問符は、このグループがオプションであることを示します。これは存在しない可能性のあるバージョン番号です。

    • -は:バージョン番号は、通常はハイフンで、他のすべてからオフに設定されているので、リテラル-文字に一致します。
    • v?:バージョン番号よりも前に使用されることがあるので、任意で文字「v」と一致します。 javascript-v8-6.0.jarなどがある場合は、これを削除してください。
    • [[:digit:]]:一桁に一致します。
    • .*.マッチ任意の文字、および*
    • 一緒

    、これらは、バージョン番号は数字が続く最初のハイフンの後は何もであることを示しています。これはpackage-3.2-beta-1.jarの場合に機能しますが、graphics-3d-7.1の場合はあまり一致しません。

  • 正規表現でグループ化されていない次の部分は、ファイル拡張子です。あなたもこれを削除したいと思われます。そうでない場合は、以下をカッコで囲み、空の置換(2番目と3番目のスラッシュの間の部分)の代わりに\2を使用します。これは「グループ2のキャプチャの内容」を意味します。バージョンは最初のキャプチャグループになり、バージョンと拡張子の両方を含む一致した式全体がグループ0になります。
    • \.:リテラル.に一致します。上で述べたように、.自体が何かにマッチするので、バックスラッシュが必要です。
    • [[:alpha:]]は:前の部分([[:alpha:]])を行い1回以上:任意の文字
    • +にマッチします。行(ファイル名)の最後にアンカー:これは.o.sh.jar.java.classの拡張など
  • $することができます。これにより、ファイル名の途中で偽の "拡張子"と一致しないようになります。

uniq --repeateduniq --repeatedは、これらの行をすべて取り、どちらが重複しているかを示します。ソートされた入力が必要ですが、lsの出力は既にソートされており、sedスクリプトはそれを変更すべきではありません。

関連する問題