Tuesday, April 30, 2024
 Popular · Latest · Hot · Upcoming
26
rated 0 times [  26] [ 0]  / answers: 1 / hits: 11637  / 1 Year ago, wed, april 12, 2023, 6:27:41

Many days ago, I found this useful bash alias (contents of my ~/.bash_aliases)



# aliases

# finds temporary files ending with '~' and deletes them
alias rm~='find . -name '*~' -print0 | xargs -0 /bin/rm -f'


Now I tried to use rm~ after cd to some directory containing 3 files ending in ~



I got this error in terminal, and files did not get deleted



find: paths must precede expression: 1n.in~
Usage: find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] [path...] [expression]


Also when I tried rm~ from /home/me, it seems to be doing nothing. Or it might be taking a lot of time.



Please tell me why am I getting error, and how to fix it.



Thanks!


More From » bash

 Answers
4

Your bash alias is not well written (the single quotes are not well used). Instead it should be:



alias rm~='find . -name "*~" -print0 | xargs -0 /bin/rm -f'


Now, I personally don't like useless uses of pipes and xargs, so your alias would be better written as:



alias rm~='find . -name "*~" -type f -exec /bin/rm -fv -- {} +'


The -type f option so as to find only files (not directories, links, etc.), the -v option to rm so as to be verbose (prints out what it's deleting). The + at the end so that find runs rm with all the found files (spawns only one instance of rm, instead of one per file).



Now from man bash:




For almost every purpose, aliases are superseded by shell functions.




Instead of an alias, it's better to use a function: comment your alias in the .bash_aliases file (i.e., put a # in front of that line), and in the file .bashrc, put this function (anywhere in the file, at the end is fine):



rm~() {
find . -name "*~" -type f -exec /bin/rm -fv -- {} +
}


Also, as the other answer mentions, you can use the -delete command to find. In this case, your rm~ function will be:



rm~() {
find . -name "*~" -type f -printf "Removing file %p
" -delete
}


In fact, you can make a cool function that will take an argument, say --dry-run, that will only output what it will delete:



rm~() {
case "$1" in
"--dry-run")
find . -name "*~" -type f -printf "[dry-run] Removing file %p
"
;;
"")
find . -name "*~" -type f -printf "Removing file %p
" -delete
;;
*)
echo "Unsupported option `$1'. Did you mean --dry-run?"
;;
esac
}


Then use as:



rm~ --dry-run


to only show the files that will be deleted (but not delete them) and then



rm~


when you're happy with this.



Adapt and extend to your needs!



Note. You'll have to open a new terminal for the changes to take effect.


[#33483] Thursday, April 13, 2023, 1 Year  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
anxietunnel

Total Points: 66
Total Questions: 120
Total Answers: 115

Location: Norway
Member since Sat, Mar 4, 2023
1 Year ago
;