How to delete files with same name with spaces in bash?

I am just about at my wit’s end here trying to find a solution to this problem.

I have a folder, and inside is another folder with files of the exact same names, i want to delete all files in the main directory that already exist in the subdirectory.

So doing that is quite simple, rm $(ls subdir/)

The problem is, if there are spaces in the filenames, the spaces will be read as newlines, so i get errors like this:

That was somewhat expected, considering i didn’t even use quotation marks… but just using quotation marks does not do the trick. I have tried just about everything i can think of, from double quotes to substitition to actual god damn for loops that try to format it correctly for the rm command, but nothing has worked, it is astonishing how resistant this command seems to be to my attempts to get iit to delete the files with spaces in their names.

My latest attempt looks like this:
for i in "$(ls subdir/ | awk '{print $0}' | sed "s/;/\";\"/g;s/^/\"/;s/$/\"/")"; do rm "$i" ; done
But no dice

I tried removing quotation marks around $i, then it’s just this again

Plz help.

What if you were to use simple conditional tests? For example,

for path in /full/path/to/maindir/*; do
    # Skip the path if it's not a regular file
    [ ! -f "$path" ] && continue
    
    # Get the basename of a file.
    # E.g: /a/b/c becomes c
    filename="$(basename "$path")"

    # Append the path of the subdir to the basename to test whether the file exists in the subdir
    file_in_subdir="/full/path/to/maindir/subdir/$filename"
    if [ -e "$file_in_subdir" ]; then
         # Delete file if it exists in subdir
         rm "$file_in_subdir"
    fi
done

Will something like this work?

Edit:

  1. Added comments.
  2. Use full path to the main directory so that the script can be invoked from anywhere and still work.
3 Likes

I don’t think i understand the code, how are the files being deleted in it?

It was only a pseudocode that you can refer to. You have to add the code to rm the file inside the second if statement.

Edit
@rabcor I edited the original post. Is it clearer now?

It worked but i had to alter it.

for path in ./*; do
    # Skip the path if it's not a regular file
    [ ! -f "$path" ] && continue
    filename="$(basename "$path")"
    file_in_subdir="./subdir/$filename"
    if [ -e "$file_in_subdir" ]; then
         # Delete file if it exists in subdir
         rm "$filename"
    fi
done

Thanks.

Yes. It was only pseudocode. I didn’t add the rm commands in it.

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.