There is a file #A.py# that appears to be a copy of the original A.py in the same directory - when I try rm, I get the following:
rm: missing operand
What does the ## notation mean? How did this file appear?
Add quotes around:
rm "#A.py#"
Without quotes it's interpreted as a beginning of the comment
You could also escape the #:
$ touch \#rmme
$ ls|grep \#
#rmme
$ rm \#rmme
Like mention in other answers by using quotes should work:
rm "#A.py#"
Also this:
rm \#A.py\#
To remove all:
rm \#*
And just in case check the option --
The rm command supports the -- (two consecutive dashes) parameter as a delimiter that indicates the end of the options. This is useful when the name of a file or directory begins with a dash or hyphen. For example, the following removes a directory named -dir1
rm -- -filename
Related
What is the correct way to use a wild card and a variable to delete many files? This is my variable "$dir"
$ echo "$dir"
/home/path/to/file
Here I have the wild card inside the double quotes, but it does not work:
$ rm "$dir/data/ffg_per_product/ffg*"
rm: cannot remove `/home/path/to/file/data/ffg_per_product/ffg*': No such file or directory
Here I have the wildcard outside the double quotes and it works:
$ rm "$dir/data/ffg_per_product/ffg"*
And here you can see the files were deleted:
$ ls -lth ffg_per_product/ffg* | wc -l
ls: cannot access ffg_per_product/ffg*: No such file or directory
0
So what I want to know, is am I using the quotes correctly to delete the files rm "$dir/data/ffg_per_product/ffg"* with the wildcard outise the quotes? Or is there another/better way?
NOTE: probably obvious to some but just for refererence and to be clear, the same applies for ls e.g. ls "$dir/data/ffg_per_product/NAME"* | wc -l, in that, does the wild card have to be outside the double quotes.
A * outside of quotes is expanded by the shell to matching filenames.
A * inside quotes is not expanded, it is used literally, just a simple *.
This is correct and corresponds to your intention:
rm "$dir/data/ffg_per_product/ffg"*
The same goes for your other example with the ls command too,
exactly the same reasoning.
I tried
rm -r #*
and
rm #*
But it just outputs this message:
usage: rm [-f | -i] [-dPRrvW] file ...
unlink file
What's the problem?
# is a shell comment. You'll need to quote it, like so:
rm '#'*
Note that the hash is in quotes and the glob is outside the quotes.
rm \#*
should do the trick for you. Remember # has got special meaning in the shell, it starts a comment.
To quote
Lines beginning with a # (with the exception of #!) are comments and
will not be executed.
Comments may also occur following the end of a command.
&
escape [backslash]. A quoting mechanism for single characters.
\X escapes the character X. This has the effect of "quoting" X,
equivalent to 'X'. The \ may be used to quote " and ', so they are
expressed literally.
Had you have files 'file1,'file2 & 'file3, to delete them you would have used :
rm \'file* #Comment : This deletes all the files starting with 'file
Reference:TLDP note on special characters
This command will list all the file starting with # and feed them to rm:
ls . |grep "^#.*" |xargs rm -rf
Working on a project within a large co. The folder for a project contains the "$" (dollar sign) character. This seems to be confusing bash when I try to change directory to this folder:
cd TEST_$_xyz
Yields an error:
No such file or directory
I'm almost sure that this is because of bash's handling of the "$" character, but I'm extremely new to bash, so I'm looking for confirmation before I force a name-change.
Thanks
You need to escape the dollar ($) sign like so. Otherwise, it treats $_xyz as an environment variable.
cd TEST_\$_xyz
example:
# In this case, $a evaluates to nothing because it is not defined
me#mypc:~/tmp/asdf$ mkdir a$a
me#mypc:~/tmp/asdf$ ls
a
# Here, I have escaped $ with \ so that it's treated like a normal $ character
me#mypc:~/tmp/asdf$ mkdir a\$a
me#mypc:~/tmp/asdf$ ls
a a$a
# changing directory to directory with escaped $ sign
me#mypc:~/tmp/asdf$ cd a\$a
me#mypc:~/tmp/asdf/a$a$
You can enclose the filename in single quotes - that way there is no variable expansion:
cd 'TEST_$_xyz'
See the "Single Quotes" section of the bash documentation
You can use...
cd TEST*xyz
(An asterix can cope with many different chars, as '$', space and others.)
In one script sh file these lines are present. I know we can do it using sed, but please let me know the way. I can use any suitable command.
BEFORE:
export HOME=${INSTALLROOT}/Subsystem
cd ${INSTALLROOT}
AFTER:
I want to add few lines after this string matches - export ASE_HOME
export HOME=${INSTALLROOT}/Subsystem
cd ${HOME}/tmp # added
rm -rf packed* # added
cd ${INSTALLROOT}
You can use this sed,
sed '/export HOME=/a cd ${HOME}/tmp # added \n rm -rf packed* # added' yourfile
man sed:
a \
text Append text, which has each embedded newline preceded by a backslash.
Just witting a simple shell script and little confused:
Here is my script:
% for f in $FILES; do echo "Processing $f file.."; done
The Command:
ls -la | grep bash
produces:
% ls -a | grep bash
.bash_from_cshrc
.bash_history
.bash_profile
.bashrc
When
FILES=".bash*"
I get the same results (different formatting) as ls -a. However when
FILES="*bash*"
I get this output:
Processing *bash* file..
This is not the expected output and not what I expect. Am I not allowed to have a wild card at the beginning of the file name? Is the . at the beginning of the file name "special" somehow?
Setting
FILES="bash*"
Also does not work.
The default globbing in bash does not include filenames starting with a . (aka hidden files).
You can change that with
shopt -s dotglob
$ ls -a
. .. .a .b .c d e f
$ ls *
d e f
$ shopt -s dotglob
$ ls *
.a .b .c d e f
$
To disable it again, run shopt -u dotglob.
If you want hidden and non hidden, set dotglob (bash)
#!/bin/bash
shopt -s dotglob
for file in *
do
echo "$file"
done
FILES=".bash*" works because the hidden files name begin with a .
FILES="bash*" doesn't work because the hidden files name begin with a . not a b
FILES="*bash*" doesn't work because the * wildcard at the beginning of a string omits hidden files.
Yes, the . at the front is special, and normally won't be matched by a * wildcard, as documented in the bash man page (and common to most Unix shells):
When a pattern is used for pathname expansion, the character “.”
at the start of a name or immediately following a slash must
be matched explicitly, unless the shell option dotglob is
set. When matching a pathname, the slash character must
always be matched explicitly. In other cases, the “.”
character is not treated specially.
If you want to include hidden files, you can specify two wildcards; one for the hidden files, and another for the others.
for f in .[!.]* *; do
echo "Processing $f file.."
done
The wildcard .* would expand to all the dot files, but that includes the parent directory, which you normally would want to exclude; so .[!.]* matches all files whose first character is a dot, but the second one isn't.
If you have other files with two leading dots, you need to specify a third wildcard to cover those but exclude the parent directory! Try ..?* which requires there to be at least one character after the second dot.
for file in directory/{.[!.]*,*};do echo $file;done
Should echo either hidden files and normal file. Thanks to tripleee for the .[!.]* tip.
The curly brackets permits a 'or' in the pattern matching. {pattern1,pattern2}