bash delete files whose filename contain asterisks - bash

How can one in bash delete files whose filename contain asterisks? I mean, using wildcards. If I do
rm -fr *filter*
I will delete all files in which the word "filter" appears in the filename, but what when the files do contain asterisk?
EDIT: Following your advice, I am not able to delete this
*filter*xyz*.data

rm -rf \*filter\* or rm -rf '*filter*'

rm -rf '*filter*'
Should work well. Use quotes (updated to single based on comment).

Related

Removing existing file in a directory

I'm trying to check if a directory if existing file, if so then I would like to remove the file before moving new file in that directory.
if [[${abc_directory}/filename*.dmp]] ; then
rm -rf ${abc_directory}/filename*.dmp
I think I am missing some logic in the if statement.
Simply do:
rm -f "${abc_directory}"/filename*.dmp
The option -f (--force) tells rm to ignore non existing files.
I have not included -r, because following your description, you will remove single files and not directory trees.
I have escaped the ${abc_directory} part to avoid issues with spaces. It assumes, that abc_directory doesn't contain any wanted wildcards/placeholders.
You're not looking for a specific file in your example, you're using a wild card. Why not just do a rm -rf ${abc_directory}/filename*.dmp before moving in the new file and be done with it?
Here's how to check for existence of a single file.
if [ -e ${abc_directory}/filename.dmp ];then
rm -f ${abc_directory}/filename.dmp
fi

Using rm -rf with a directory

I tried to search on SO, but not able to find the difference between the following commands. if I have a directory named dir, how the below commands differ?
rm -rf dir/*
rm -rf dir/
rm -rf dir
Also how do the user permissions on the directory affect the outcome, if the id running the command is not the owner or not even in the group of the owner?
I am adding the command to do rm -rf in a shell script I am working on and need help in understanding the difference between the above commands.
rm -rf dir/*
Removes files within the directory (without removing the directory itself).
Note, hidden files won't be removed.
rm -rf dir/
Trailing slash indicates that dir is a directory. If it was a file, it wouldn't get removed. In your case this is identical to rm -rf dir, but in general it differs (see below)
rm -rf dir
In your case, identical to the one above.
In general, tools such as rm usually follow IEEE/OpenGroup standards when it comes to pathname resolution, which means that dir/ is equivalent to dir/.. One implication of that is that if diris a symlink to a directory rm -rf dir/ will remove the content of the directory (including the hidden files) but not the link or the directory itself, whereas rm -rf dir will only remove the symlink.
You need to have write permissions on a file or directory that you are removing, plus exec permissions on a directory that rm needs to traverse to remove files. You can read more about Unix filesystem permissions here.

How to delete a file named "~" in Mac?

I run the following command on my Macbook:
mkdir ~/tmp/~
Now, I want to delete this ~/tmp/~
.
How to do it? It is not a link actually, if I run rm -rf ~/tmp/~, the home files are all dropped.
So interesting. This task can be done in this way.
# This form is safe and functional.
rm -rf ~/tmp/~
But if you try to do this, your home data is going to be lost:
# THIS FORM IS DANGEROUS; DO NOT USE IT
cd ~/tmp
rm -rf ~
I agree with Ivan X in his comment, the ~ in this context does not cause any particular problems and rmdir ~/tmp~ removes the directory without problem (see #1 below).
However, what you describe is a classic Unix/BSD problem. In order to remove a directory that contains special characters you have to make sure your shell ignores interpolation of them. There are two methods to achieve this.
You can use a full path, e.g. rmdir ~/tmp/~ or...
In the case of a file or directory starting with -, you can use -- to tell the shell that there are no options following, ala rmdir -- -foo-
So interesting. This task can be done in this way.
# This form is safe and functional.
rm -rf ~/tmp/~
But if you try to do this, your home data is going to be lost:
# THIS FORM IS DANGEROUS; DO NOT USE IT
cd ~/tmp
rm -rf ~
Quite so, and quite simply because (see Tilde Expansion):
If a word begins with an unquoted tilde character
(‘~’), all of the characters up to the first
unquoted slash (or all characters, if there is no unquoted slash) are
considered a tilde-prefix. If none of the characters in the
tilde-prefix are quoted, the characters in the tilde-prefix following
the tilde are treated as a possible login name. If this
login name is the null string, the tilde is replaced with the value of
the HOME shell variable.
Thus, rm -rf ~ is expanded as rm -rf $HOME.
Deletion of any file with a funny name is better done with a File browser. It is simply easier and safer.
If you don't want to use Finder, use any other text based file browser, e.g. emacs dired mode.
[...]
In case you insist in doing this using a shell...
ls -i # will show you the inode number of the files you have
Once you have the right inode, say 123456789, you can use find to delete it.
find . -maxdepth 1 -type f -inum 123456789 -delete

what is the diff between rm -rf $TIGER/${LION}/${RABBIT}/* and rm -rf $TIGER/${LION}/${RABBIT}?

I need to understand the diff between rm -rf $TIGER/${LION}/${RABBIT}/* and rm -rf $TIGER/${LION}/${RABBIT} so that putting this in script won't produce the disaster making it to delete everything it can from root in case that the variables are not set. what is the safe way to use rm -rf in csh/ksh?
Thanks for help !!
Either of those commands would create a disaster if the variables were all unset; they differ only in whether they delete the directory itself, or its non-hidden contents.
If you want to be safe against deleting recursively from the root directory, explicitly test for that case and cancel:
[[ $TIGER && $LION && $RABBIT ]] || {
echo "TIGER, LION and RABBIT must all be set; script exiting"
exit 1
}
rm -rf ...
This recursively deletes all non-hidden files inside the ${RABBIT} directory - ${RABBIT} directory is not deleted:
rm -rf $TIGER/${LION}/${RABBIT}/*
Note hidden files (aka dot files) have filenames beginning with .. These are not matched with typical * expansion unless shell dotglob option is set.
So to delete all files (including hidden files) you could use shopt thus:
shopt -s dotglob # turns shell option dotglob ON
rm -rf $TIGER/${LION}/${RABBIT}/* # Now deletes all (including hidden) files
shopt -u dotglob # FYI - unsets or turns dotglob OFF
This recursively deletes everything including the ${RABBIT} directory.
rm -rf $TIGER/${LION}/${RABBIT}
putting /* at the end will delete contents inside that directory
while only "/" will delete the directory itself as well as contents inside it.

Explaining the rm ./-rf "trick"

This question states:
It is amazing how many users don't know about the rm ./-rf or rm -- -rf tricks.
I am afraid to try these, but curious as to what they do. They are also very difficult to search...
Can someone enlighten me?
rm ./-rf and/or rm -- -rf would attempt to remove a file named, specifically, -rf
The only trick here is that you normally can't delete a file that starts with a "-" because the command will assume it's a command argument. By preceding the file with a full path, or using the -- option (which means, end all options) the command will no longer assume it's an argument.
It should be noted that the -- version of this trick may or may not work with all shell commands either, so it's best to use the first version.
If you have a file named -rf in your directory, it is difficult to remove that file if you don't know the trick. That's because:
rm -rf
supplies two command line options (-r and -f) as a single argument, and tells rm to recursively and forcibly remove things.
If you write:
rm ./-rf
the argument does not start with a dash any more, so it is simply a file name. Similarly, by common (but not universal) convention, -- marks the end of the option arguments and anything afterwards is no longer an option (which usually means it is a file name). So:
rm -- -rf
removes the file because rm knows that the arguments that follow the -- are file names, not options for it to process.
The file -rf is even more dangerous if you use wildcards:
rm *rf*
Suddenly, this will remove directories as well as files (but won't harm the file -rf).
Not a complete answer, as I think the other answers give good explanations.
When I'm unsure what a given rm invocation is going to delete, I try to remember to simply ls the file list first to make sure it is actually what I want to delete:
$ ls -rf
-rf .. .
$
OK, clearly thats not right, lets try again:
$ ls ./-rf
./-rf
$
Thats better. Lets do a history replacement of ls with rm -v (-v just for extra paranoia/checking) and do the actual delete:
$ rm -v !!:*
rm -v ./-rf
removed `./-rf'
$
This also works nicely with wildcards, brace expansions, etc, when you're not sure what the expansion will be exactly.
Also if you're wondering how files like -rf get created in the first place, its astonishingly easy if you mess up a redirection a bit:
$ ls
$ echo > -rf
$ ls
-rf
$

Resources