Recently my NAS was ransomware attacked and all my files were 7zipped. I managed to get the password and extract them and at the same time I renamed the 7zipped file to 7z.bad (so that it's easier later to delete just the affected files and not any actual .7z files I already had before the attack).

This is the script I used to extract and rename the files:

while [ -n "$(find . -type f -name '*.7z' -print -quit)" ]
    find . -type f -name "*.7z" -execdir /usr/local/sbin/7z x -pPASSWORD {} \; -execdir mv {} {}".bad" \;

So, what I have now is a lot of duplicates, like this:

Phone book.xlsx
Phone book.xlsx.7z.bad

What I would like to do is:

  1. Look for any .7z.bad files in the current directory (and all subdirectories)
  2. For any .7z.bad file found, if the same file without .7z.bad extension is also present:
  3. Delete the .7z.bad file

The reason I want to check for the original file's presence is just for another level of security.

I am afraid I won't be able to install any other tools (like fdupes) in my Qnap NAS.

2 Answers 2

find . -type f -exec sh -c 'for name do rm -f -- "$name.7z.bad"; done' sh {} +

The above finds all regular files in or below the current directory, and then tries to delete all of them, but adds .7z.bad to the end of the names first.

This way, all files with names ending in .7z.bad are deleted if there are corresponding files without that filename suffix.

Testing in an otherwise empty directory:

$ touch file-{1..5}.txt.7z.bad
$ touch file-{1..3}.txt
$ ls
file-1.txt        file-2.txt        file-3.txt        file-4.txt.7z.bad
file-1.txt.7z.bad file-2.txt.7z.bad file-3.txt.7z.bad file-5.txt.7z.bad
$ find . -type f -exec sh -c 'for name do rm -f -- "$name.7z.bad"; done' sh {} +
$ ls
file-1.txt        file-2.txt        file-3.txt        file-4.txt.7z.bad file-5.txt.7z.bad
  • what is the need for bringing in the shell when all you're doing is removing the files? -exec rm -f {} + would delete just as well
    – guest_7
    Commented Aug 23, 2021 at 10:22
  • 1
    @guest_7 I'm not actually deleting the pathnames that find gives me, I add a filename suffix to each name first. Otherwise I would remove all files!
    – Kusalananda
    Commented Aug 23, 2021 at 10:24
  • Iam not sure to follow this? It will also delete file that has double.7z.bad extension? But otherwise a good approach!
    – guest_7
    Commented Aug 23, 2021 at 10:32
  • @guest_7 It will certainly try to delete files that have .7z.bad.7z.bad filename suffixes. That's ok though as they don't exist and I'm running with rm -f (which means the deletion of non-existent files won't be generating any errors).
    – Kusalananda
    Commented Aug 23, 2021 at 10:49
find . -type f -name "*.7z.bad" -exec sh -c '
  for file; do
    if [ -f "${file%.7z.bad}" ]; then
      rm -- "$file"
      echo "keeping file $file" >&2
' sh {} +

This passes all filenames found by find to the shell script which then loops over the filenames and checks if each filename without the .7z.bad suffix exists. If this is the case, it deletes the file with the .7z.bad suffix or prints a warning message otherwise.

Replace -f with -s if you want to test if the unzipped file exists and has a non-zero file size.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .