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.