bash で，unzip の結果作られたファイルの一括削除


このような状況で

[code]

    $ pwd
    ~/Desktop
    $ ls myzip*
    myzip.zip
    
[/code]

`~/Desktop/myzip/` 下に解凍されることを期待して間違ってこうしてしまうことがあります：

[code]

    $ unzip myzip.zip
    
[/code]

結果

[code]

    $ tree
    ├── extracted_file0
    ├── extracted_file1
     . ... 
    ├── myzip.zip
     ... # 元から ~/Desktop にあったファイルたちに混ざってしまっている
    
[/code]

大惨事となってしまったので，元の状況に戻したい． 既存のファイルがすでに上書きされてしまった場合は無視できるとして，どのようにすれば `unzip`
で意図せずディレクトリ上にばら撒かれてしまったファイル群を消し去ることができるでしょうか．

なお， すでに試みたこととしては， `unzip -l myzip.zip` で次のような書式のテキストが得られることを知り

[code]

    Archive:  myzip.zip
      Length      Date    Time    Name
    ---------  ---------- -----   ----
          119  2015-01-02 16:05   hashas.hs
          274  2015-01-25 16:05   piepie.py
    ---------                     -------
          393                     2 files
    
[/code]

とりあえずこれをファイルに書き込んで `vim` でファイル名のリストに整形し， `cat files.txt | xargs rm`
でいちおう対処しました．もう少し場当たり的でない方法を知りたいです．




`unzip -l` の結果を加工します。

[code]

    unzip -qq -l myzip.zip | perl -ane 'print "$F[-1]\n"' | xargs rm
    
[/code]

実際には、出力結果を見た上で xargs rm するのが良いと思います。

空白が混じっている場合は、NUL で区切ると良いです。

[code]

    unzip -qq -l myzip.zip | perl -ne 'chomp; @F = split " ", $_, 4; print "$F[-1]\0"' | xargs -0 rm
    
[/code]

同名のファイルがあって `unzip` で上書きしなかったからそれは残したいという場合は、最終アクセス時刻 (atime)
で判定するのが良いかもしれません。ここでは、1時間以内 (24分の1 日) のものを対象にしています。

[code]

    unzip -qq -l myzip.zip | perl -ne 'chomp; @F = split " ", $_, 4; print "$F[-1]\0" if -A $F[-1] < 1/24'|xargs -0 rm
    
[/code]

※ @heliac2001 のコメントを元に、`-qq` を使うよう修正しました。空白を気にしない場合は sed を使っても良さそうです。




以下は回答ではありません。この様な事故をどの様に防いだら良いのか、というお話です。

もともと、unzip
コマンドはアーカイブの内容をそのまま展開してしまいます。そのため、アーカイブ内のファイルが単一のディレクトリに収められていない場合には今回の様な事故が発生してしまう可能性があります。もっとも、単一のディレクトリに収められていても、カレントディレクトリに同名のディレクトリがあれば同じことですが。。。  
一応、unzip には `-d`
オプションがあって、指定したディレクトリにアーカイブの内容を展開してくれます。指定ディレクトリがない場合には勝手に作成してくれます。

[code]

    $ unzip -d output myzip.zip
    $ ls output
    c001.txt  c002.txt  c003.txt ...
    
[/code]

しかし、毎回ディレクトリを指定するのは疲れますし、指定し忘れるとやはり…。

そこで、unzip
以外に何か目的に適うコマンドはないだろうかと思いまして調べてみた所、[unar](http://unarchiver.c3.cx/commandline)
が見つかりました(まぁ、以前から使っていたのですけどね)。

> unar(1)
>
> -d, -force-directory  
>  Always create a containing directory for the contents of the unpacked
> archive. **By default, a directory is created if there is more than one top-
> level file or folder**.

今回の `myzip.zip` の場合には `myzip` ディレクトリを作成してその中に展開してくれます(アーカイブの basename
でディレクトリを作成)。  
その他にもこんなオプションがあります。

> -r, -force-rename  
>  Always rename files when a file to be unpacked already exists on disk.

例えば、`a.txt` というファイルが既にある場合には `a-1.txt` にリネームしてくれます。

ご参考までにどうぞ。

