Unable to copy a file with '$' in name in Linux - linux

Inside of my Linux directory, I have a file named TopSample$Config.class.
Whenever I try to copy this file to another location/directory, it is not allowing me to do so.
I am doing it this way:
cp TopSample$Config.class /home/praveen/com/config/
Please let me know if this isn't possible.

The shell will interpret $Config as a variable. And it will expand to empty string.
You can put single quotes around to keep the literal value:
cp 'TopSample$Config.class' /home/praveen/com/config/
Another way is to escape the $(dollar sign) by using \(backslash)
cp TopSample\$Config.class /home/praveen/com/config/

Put single quotes around the filename.
cp 'TopSample$Config.class' /home/praveen/com/config

Or replace the offending character with the filename metacharacter of '?', meaning "any one character". Note that while this might be more convenient and requires the fewest keystrokes, be aware that a filename of TopSample?Config.class will also match TopSampleaConfig.class, TopSamplebConfig.class, TopSamplecConfig.class, etc.

Related

bash handling of quotation marks in filename

I am trying to remove and replace quotation marks that are present in a file name. For example, I would like to change:
$ ls
abc"def"ghi"jkl"mno
to this
$ ls
abc:def:ghi:jkl:mno
In trying to solve this, I came across How to rename a bunch of files to eliminate quote marks, which is exactly what I want to do. However, it didn't work for my case. To figure out why, I tried creating a test file like this:
$ touch abba\"abba\"cde\"cde\"efef
With this file, the solutions I came across (such as mentioned above) worked. But why didn't it work for the first file?
One thing I discovered was that bash command completion sees them differently. If I type in
$ ls abb<tab>
bash will complete the filename like so:
$ abba\"abba\"cde\"cde\"efef
just as I created it. But for the original file, bash completion went like this:
$ ls abc<tab>
results in
$ abc"def"ghi"jkl"mno
So in the test case file, there is an escape of the quotation marks, and in the other case (the file I really want to rename), there is no escaping of the the quotation marks. I don't know how the original files were named.
Can anyone explain why bash sees these names differently, and how I would go about renaming my file?
Here is two ways to rename a file with "(quotation) mark,
option 1: With escape character \
mv abc\"cdf\"efg\"hij newFileName
option 2: By using '(single quote)
mv 'abc"cdf"efg"hij' newFileName
Note: using special charaters like :(colon) in file name might not be a good idea,
and regarding the auto completion, it usually fill the name with escape character, example
ls abc<tab> will complete the name to ls abc\"cdf\"efg\"hij
unless you start the name with a quote, example
ls 'abc<tab> will complete the name to ls 'abc"cdf"efg"hij'

Replace extension using basename in one line of code

In bash linux
v1=$(basename $0) gives filename.ext
v1=${v1%.*}.log replaces ext filename.log
how to combine in one line? When I try below I get bad substitution error
v1={($(basename $0))%.*}.log
thank you
You can only use parameter expansion on parameters, so in general you can't do this.
However, in this specific case you can reorder the operations since it doesn't matter whether you basename or strip extension first:
v1=$(basename "${0%.*}.log")

vim :gsearch (greplace plugin) escaping characters

I am using the greplace plugin for vim and am not sure how to escape brackets in a search.
I want to search for cookies[:parent] and have tried:
:Gsearch cookies[:parent] # returns nothing
:Gsearch cookies\[:parent\] # returns nothing
How should I be doing this?
Thanks
Try
Gsearch cookies\\\[:parent\\\]
or
Gsearch 'cookies\[:parent\]'
. If I understood correctly, shell invoked by :grep! invoked by :Gsearch gets string grep -n cookies\[:parent\] /dev/null (assuming grepprg option has default value) and thus your escapes are interpreted by shell that thinks they are for escaping [ in order to prevent glob expansion. But after globbing done by shell grep takes argument as a pattern, so you need to escape it for grep also and it is why I have three backslashes here: two are to make grep get a backslash and third to prevent glob expansion.
:Gsearch cookies\\\[:parent] works for me.
Remember that :Gsearch requires a file mask in addition to the pattern, so in reality, you'd want to type something like :Gsearch \\\[:parent] *.php or whatever, to specify which files you want to have searched.
:Gsearch cookies\[:parent]
[ is the start of a character class, so needs to be escaped. The ] isn't particularly special so doesn't need to be escaped.

Linux rename function not being used correctly

I'm trying to use the rename command in a Terminal in Ubuntu to append a string to the beginning of some avi file names as follows.
rename -n 's/(\w)\.avi$/String_to_add__$1\.avi/' *.avi
So I expect the following:
String_to_add_MyMovie.avi
Problem is that when I run the command it appends the string to the end of the file name, so I end up with the following:
MyMovie_String_to_add_.avi
I'm not sure if I have the perlexpr syntax wrong or something else. Any insight is appreciated.
UPDATE:
Thanks for the suggestions, I tried the suggestions from alno and plundra and made the following modification:
rename -n 's/(\w+)\.avi$/String_to_add__$1\.avi/' *.avi
But now the file gets the string inserted in the middle of the name as follows:
My_String_to_add_Movie
My apologies though, I neglected to mention that the titles are preceded by 3 numeric values, so the file name nomenclature is {3 numbers}-My_Movie.avi so for example 001-My_Movie.avi. But I didn't think this would make a difference since I'm assuming \w+ matches alphanumeric characters, might the '-' be the issue?
Haven't tried Christian's approach yet, I want to be able to use the rename command, or at least understand why it's not working before I try a different approach.
I don't think rename -n is standard. You could do this:
for i in *.avi; do mv $i String_to_add_$i; done
You're only matching a single character with \w, you want \w+, so the complete line would be:
rename -n 's/(\w+)\.avi$/String_to_add__$1\.avi/' *.avi
Correct version:
rename -n 's/(\w+)\.avi$/String_to_add__$1\.avi/' *.avi
You simply forgot + after \w, so it tried to match only one character.

linux batch rename directories and strip # character from name

i have a directory with a lot of subdirectories with a # infront of them:
#adhasdk
#ad18237
I want to rename them all and remove the # caracter
I tried to do:
rename -n `s/#//g` *
but didn't seem to work.
-bash: s/#//g: No such file or directory
Any ideas on this.
Thanks
Just use
$ rename 's/^#//' *
use -n just to check that what you think it would happen really happens.
In you example you have the clue about the wrong quotes used (backticks) in the error message
-bash: s/#//g: No such file or directory
bash is trying to execute a command named s/#//g.
No that using g (global) and not anchoring the regular expression you will replace any #, not just the one in the first position.
I don't know whether it's just a typo when you typed it here, but that "rename" command should work if:
you leave off the "-n" and
you quote the substitution with regular single-quotes and not back-quotes
The "-n" tells it to not really do anything. The back-quotes are just wrong (they mean something but not what you want here).
The problem is that you use backticks (`). You should use normal quotes:
rename -n 's/#//g' *
for DIR in \#*/
do
echo mv "$DIR" "${DIR/#\#/}"
done
I had to rename all folders inside a given folder. Each folder name had some text inside round braces. The following command removed the round braces from all folder names:
rename 's/(.+)//' *
Some distros doesn't support regexp in rename. You have to install prename. Even more, sometimes you can't install prename and you have to install gprename to have binary prename.
If you have 'prename' then just change backtick character " ` " to single quote and everything should work.
So the solution should be:
prename -n 's/#//g' *
or
prename -n 'y/#//' *

Resources