4

Sometimes I will do a command such as

unzip tons_of_files.zip

And I will forget to put a -d to point to a subdirectory. This causes the current folder to get filled with tons of files that are intermixed with the existing files.

What is the best way to remove all these new files and/or move them to a new directory? I want to avoid having to manually examine the directory and determine if the file was part of the archive or was already present.

5

A quick way might be the following:

unzip -qql tons_of_files.zip | while read -r l d t n ; do rm -fr "$n" ; done

As this does automatic erasures: use it at your own risk. To see a preview replace ... rm ... with ... echo rm ....

1

If you extracted the files in a directory where you hadn't modified or moved any files for a few minutes before the extraction, you can tell the extracted files by their very recent ctime. This isn't perfect (if a directory contains an extracted file, you can't tell whether it was created by unzipping or it existed before (perhaps being empty)) but works reasonably well in practice.

The following GNU find command moves files and directories in the current directory whose ctime is less than 2 minutes ago to /other/dir. ls -lctr may help find a suitable cutoff time.

find . -mindepth 1 -maxdepth 1 -cmin -2 -exec mv {} /other/dir \;

Zsh equivalent:

mv *(cm-3) /other/directory

The following GNU find command moves files with a similarly recent ctime in the directory tree rooted at the current directory to a similar path under /other/dir.

find . -mindepth 1 -cmin -2 -type f -exec sh -c '
    for x; do
      mkdir -p "$0/${x%/*}"
      mv "$x" "$0/$x"
    done
  ' /other/dir {} +

Zsh equivalent (almost: this one reproduces the entire directory hierarchy, not just the directories that will contain files):

autoload zmv
mkdir -p ./**/*(/cm-3:s"|.|/other/dir|")
zmv -Q '(**/)(*)(.cm-3)' /other/dir/'$1$2'
1

$ for i in `unzip -qql tons_of_files.zip | tr -s " "| cut -d" " -f 5 | sed 's/^.*///'`; do echo $i; done

Change echo to rm.

What it is doing (inside the backticks):

  1. list files (one-bye-one)
  2. squeeze spaces
  3. select 5th field
  4. delete everything that is folder name
0

Assuming your current working directory is the folder where you accidentally extracted the file:

unzip -Z1 ../../accidentally-extracted.zip | xargs rm

Explanation:

  1. unzip -Z1 lists all files in the zip file line by line
  2. xargs passes each line as an argument to rm

If you are not inside the folder you accidentally extracted to, you can end up unintentionally deleting files if they match one of the files in the zip.

If you are unsure, you can run xargs with -p to make it prompt you for each execution. You can do the first couple of executions to be sure that you didn't mess up something.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.