how to remove files in a list of paths easily?

Solution 1:

What's your input? A file? A command? Either way, xargs should be helpful:

cat file | xargs rm

... will delete every path for every line in the file. If it's just a command that's outputting a path on each line, pipe it through xargs and it should work well.

Alternatively, use xargs --arg-file="file.txt" rm. This saves on pipe and unnecessary cat.

If you're looking to do more with each line, you could use a traditional bash while loop:

# uses echo for testing
# remove # before rm for actual deletion
while read -r path; do
    echo "deleting $path"
    # rm "$path"
done < file

If your list is the output of find, you have another couple of options, including a -delete option or using -exec rm {} \+. There are almost certainly a few dozen other viable routes to success. If you're doing automated deletion with find, just check the output before you delete. It won't forgive you your mistakes.

Spaces can be a problem with piping things into xargs. This might not be an issue for you and your locate but both locate and xargs have a way of getting around that. They can both choose to use the \0 null character as a delimiter instead of return lines. Yay. In short, your command becomes:

locate -0b libavfilter.so | xargs -0 rm

Solution 2:

Pipe the output to xargs:

echo "/usr/lib/i386-linux-gnu/libavfilter.so
/usr/lib/i386-linux-gnu/libavfilter.so.3
/usr/lib/i386-linux-gnu/libavfilter.so.3.42.103
/usr/lib/i386-linux-gnu/i686/cmov/libavfilter.so
/usr/lib/i386-linux-gnu/i686/cmov/libavfilter.so.3
/usr/lib/i386-linux-gnu/i686/cmov/libavfilter.so.3.42.103
/usr/local/lib/libavfilter.so
/usr/local/lib/libavfilter.so.4
/usr/local/lib/libavfilter.so.4.4.100" | xargs rm

Or if your list is in a file:

cat file | xargs rm

Solution 3:

At the very basic level this can be done in Python:

import os

with open('input.txt') as f:
    for line in f:
        os.unlink(line.strip())

In case you have exotic filenames (such as created with touch with$'\n'backslash or with$'\n'newline, which is very bad idea, but possible ) you could use an input file as so:

./with\backspace
./with\nnewline

And handle everything in Python 3 as so:

import os

with open('./input.txt') as f:
    for l in f:
        # alternatively one can use 
        # bytes(l.strip(),sys.getdefaultencoding())
        bytes_filename =  bytes(l.strip(), 'utf-8').decode('unicode_escape')
        f_stat = os.stat(os.fsdecode( bytes_filename ) )
        print(l.strip(),f_stat)

There's a way of doing that in Python 2 as well.