I am having some issues deleting some folders in unix.
Directory 1:
?0\'
Directory 2:
-1\'
I would like to delete them recursively so something like
rm -rf -1\'
Not sure on how to escape the quotes, dashes and question marks.
You need to use quotes when they are fishy characters, then use a wildcard outside of the quotes. Without quotes those characters would want to preform other tasks.
rm -rf -- *"\'"
Thanks to a comment by osgx
Be careful; check carefully before you execute any rm -fr on weird directory names.
The standard trick for file names (directory names) starting with a dash - is to prefix the name with ./ so that it doesn't start with - any more:
rm -fr ./-1??
The other directory could perhaps be identified by:
rm -fr ./?0??
I would, at the very least, run:
echo ./-1?? ./?0??
before trying the rm commands, to ensure that only the correct directories are picked up. The rm command is dangerous if you're not certain that it is doing what you want.
The notation using questions marks avoids having to quote the question marks, backslashes and single quotes, in part out of a suspicion that what shows on the terminal may not be the name in the file system. You may need to do further work to identify the names, such ls | od -c or similar commands to validate the exact spelling of the directory names.
Related
Unfortunately zsh: how to delete contents in folder without deleting the folder? does not have any good answer.
I'm currently using rm -rf {.,}* and if that fails because there is no hidden file in the folder I do another rm -rf *. This is of course annoying, not least because I am prompted for confirmation twice (so just putting them in a row with ; wouldn't solve much.)
Is there a solution that
works in the presence and absence of hidden files;
does not delete the current folder, even temporarily;
prompts only once?
It must work in the current folder. If it also works for a specified folder, that's nice to have but not a must.
zsh has the GLOB_DOTS setting to make * match hidden files; you can enable this globally with setopt glob_dots if you want, or for a pattern with the (D) glob qualifier.
% print dir/*(D)
So to remove all files (hidden and unhidden) you can use:
% setopt glob_dots
% rm -rf dir/*
# Disable glob_dots for just this pattern:
% rm -rf dir/*(^D)
Or:
% rm -rf dir/*(D)
Unless I missed something, I believe this should do what you want.
For more information see man zshexpn (which is comprehensive, but also quite dense and not an easy read; section 5.9 of the Zsh User Guide is a more gentle introduction, and I recommend spending some time reading through all of the User Guide because there's lots of useful things in there).
You can delete the files inside a folder without deleting the actual folder by just adding * after a slash, for example:
rm -f my_folder/*
That way it will delete all files inside my_folder but not the actual folder itself. You can use the option r to recursive delete all inside the folder.
Update for one liner:
You could then use in the same command:
rm -rf my_folder/* my_folder/.*
I have to delete a number of files with names like "test excel-27-03-2016.xls" from a directory on a Unix machine. Can you please suggest how? I tried using command
rm -f test excel-27-03-2016.xls
but it is not deleting the file.
Does the name of the file contains a space? It seems so.
If this is the case, rm -f "test excel-27-03-2016.xls" (note double quotes around the file name) ought to do it.
Running rm -f test excel-27-03-2016.xls means trying to erase two files, one named test and the other excel-27-03-2016.xls.
So if 'test excel-27-03-2016.xls' is one filename, you have to escape the space in the rm command.
rm test\ excel-27-03-2016.xls
or
rm 'test excel-27-03-2016.xls'
otherwise rm will think 'test' and 'excel-27-03-2016.xls' are two different files.
(Also you shouldn't need to use -f.)
For a single file, if the file name contains spaces, you have to protect those spaces. By default, the shell splits file names (arguments in general) at spaces. So, enclose the name in double quotes or single quotes:
rm -f "test excel-27-03-2016.xls"
or use a backslash if you prefer (but I don't prefer backslashes; I normally use quotes):
rm -f test\ excel-27-03-2016.xls
When a delete operation doesn't work, the -f option to rm becomes your enemy; it suppresses the error messages that rm would otherwise give. For example, without the -f, you might see:
$ rm test excel-27-03-2016.xls
rm: test: No such file or directory
rm: excel-27-03-2016.xls: No such file or directory
$
That tells you that rm was given two names, not one as you intended.
From a comment:
I have 20-30 files; do I have to give rm 'test excel-27-03-2016.xls" each time and provide "Yes" permission to delete file?
Time to learn wild-cards. First thing to learn — Be Careful! Do not destroy files carelessly.
Run a command such as:
ls -ld *.xls
Does that list the files you want deleted — all the files you want deleted and nothing but the files you want deleted? If it doesn't contain any extra file names (and no directory names), then you can run:
rm -f *.xls
If it doesn't contain all the file names you need deleted, but it does contain only names that you need deleted, then run the rm to reduce the size of the problem, then devise an alternative pattern to delete the others:
ls -ld *.xlsx # Semi-plausible
If it contains too many names, you have a couple of options. One is to use rm interactively:
rm -i *.xls
and respond yes to those that should be deleted and no to those that should be kept. Another is to work out a more precise wildcard, perhaps *-27-03-2016.xls.
When using wild-cards, the shell keeps file names as single arguments, so the fact that the generated names have spaces in them isn't a problem. Be aware that many shell techniques, such as capturing that list of file names in a variable, do not preserve the spaces properly — a cause of much confusion.
And, with any mass file removal, be very careful. The Unix system will not stop you doing immense damage to your files It will take you at your word — if you say 'remove everything', it will try to do so.
From another comment:
I have taken root access so I will have all permissions.
Don't run as root when you have problems working out what you are doing. Running as root means that any mistake has the potential to be dramatically more devastating than if you run as yourself.
If you are running as root, the -f option to rm really isn't needed (unless someone has attempted to protect you by creating an alias for the rm command).
When you're root, the system does what you tell it to do. root: Remove the kernel. system: Yes, sir! Right away, sir! root: Remove the complete root file system. system: Yes, sir! Right away, sir!
Be very, very careful when running as root. It is a bad idea to experiment when running as root. It is very important to know exactly what you plan to do as root, to gain root privileges and do what you plan to do, and then lose the root privileges as soon as possible. Use sudo (or su) to temporarily gain root privileges.
I am currently trying to remove a number of files from my root directory. There are about 110 files with almost the exact same file name.
The file name appears as wp-cron.php?doing_wp_cron=1.93 where 93 is any integer from 1-110.
However when I try to run the code: sudo rm /root/wp-cron.php?doing_wp_cron=1.* it actually tries to find the file with the asterisk * in the filename, leaving me with a file not found error.
What is the correct notation for removing a series of files using wildcard notation?
NOTE: I have already tried delimiting the filepath with both single ' and double quotes ". This did not avail.
Any thoughts on the matter?
Take a look at the permission on the /root directory with ls -ld /root, typically a non-root user will not have r-x permissions, which won't allow them to read the directory listing.
In your command sudo rm /root/wp-cron.php?doing_wp_cron=1.* the filename expansion attempt happens in the shell running under your non-root user. That fails to expand to the individual filenames as you do not have permissions to read /root.
The shell then execs sudo\0rm\0/root/wp-cron.php?doing_wp_cron=1.*\0. (Three separate, explicit arguments).
sudo, after satisfying its conditions, execs rm\0/root/wp-cron.php?doing_wp_cron=1.*\0.
rm runs and attempts to unlink the literal path /root/wp-cron.php?doing_wp_cron=1.*, failing as you've seen.
The solution to removing depends on your sudo permissions. If permitted, you may run a bash sub-process to do the file-name expansion as root:
sudo bash -c "rm /root/a*"
If not permitted, do the sudo rm with explicit filenames.
Brandon,
I agree with #arkascha . That glob should match, so something is amiss here. Do you get the appropriate list of files if you use a different binary, say 'ls' ? Try this:
ls /root/wp-cron.php?doing_wp_cron=1.*
If that returns the full list of files, then you know there's something funny with your environment regarding rm. This could be an alias as suggested.
If you cannot determine what is different or wrong with your environment you could run the list of files through a for loop and remove each one as a work-around:
for file in `ls /root/wp-cron.php?doing_wp_cron=1.*`
do
rm $file
done
What does rf in rm -rf in Unix stand for?
More generally, I have a hard time remembering Unix commands and options because I don't understand what they stand for. Is there a resource that explain the meaning of these shorthands?
In rm,
-r stands for recursive
-f stands for force
Doc :
man rm
said :
-f, --force
ignore nonexistent files and arguments, never prompt
-r, -R, --recursive
remove directories and their contents recursively
rm means remove
r means recursive, which you have to use when removing an entire folder
f means force removal
combined, rm -rf someDirectory means force the recursive removal of someDirectory
-r
Recursively removes directories and subdirectories
in the argument list. The directory will be emptied
of files and removed. The user is normally prompted
for removal of any write-protected files which the
directory contains. The write-protected files are
removed without prompting, however, if the -f
option is used, or if the standard input is not a
terminal and the -i option is not used.
I believe it is recursive force
I am have a simple egrep command that searches through all the files in the current directory for lines that contain the word "error":
egrep -i "error" *
This command will also go through the sub-directories as well. Here is a sample of what the whole folder looks like:
/Logfile_20120630_030000_ID1.log
/Logfile_20120630_030001_ID2.log
/Logfile_20120630_030005_ID3.log
/subfolder/Logfile_20120630_031000_Errors_A3.log
/subfolder/Logfile_20120630_031001_Errors_A3.log
/subfolder/Logfile_20120630_031002_Errors_A3.log
/subfolder/Logfile_20120630_031003_Errors_A3.log
The logfiles at the top directory contain "error" lines. But the logfiles in the "subfolder" directory do not contain lines with "error". (only in the filename)
So the problem I am getting is that the egrep command seems to be looking at the information within the "subfolder". My result gets a chunk of what seems to be binary block, then the text lines that contain the word "error" from the top folder logfiles.
If I deleted all the files underneath "subfolder", but did not delete the folder itself, I get the exact same results.
So does Unix keep file history information inside a folder??
The problem was corrected by running:
find . -type f | egrep -i "error" *
But I still dont understand why it was a problem. I'm running C-shell on a SunOS.
egrep -i error *
The * metacharacter matches ANY file name. Directories are files, too. * is expanded by the shell into any and all files in the current directory, this is traditionally called globbing.
set noglob
turns off that behavior. However, it is unlikely there are files named * in your directory, so in this example the command would find no files of any kind. BTW - Do not create a file named * to test this, because files named * may cause all kinds of interesting and unwanted things to happen. Think about what might happen when you tried to delete the file? rm '*' would be the right command, but if you or someone else did a rm * unthinkingly then you have problems...