I have a variable containing a string with a quote:
echo $variable
It's my variable
to be able to use this variable as a legend for ffmpeg, I need to add 5 backslashes before the quote:
variable="It\\\\\'s my variable"
I'm confused as to what syntax I should use, as the backslashes and quotes have very specific meanings in bash replace commands. I have tried this:
variable=`echo $variable | tr "'" "\\\\\'"`
but it does not produce the correct result
You can just use some single quotes yourself to tell bash not to interpret those slashes:
variable="It"'\\\\\'"'s my variable"
Edit: To convert an existing variable use:
variable=${variable//\'/'\\\\\'\'}
This works fine, is portable and does not have the problems of sed:
echo "$v" |perl -pe "s/'/\x5c\x5c\x5c\x5c\x5c'/g"
PS: \x5c is the ascii code of slash \
Related
I am looking for a way to convert a multiline string in a variable in bash to a single-line string that has each \n character escaped as the \n literal.
For example:
str="
Hello
World
"
I need this to become Hello\nWorld. I looked through the questions on SO and Unix StackExchange but I haven't been able to find a command yet that achieves what I need.
Bash has two built-in ways to quote values suitable for re-ingestion. These will handle not only newlines but also tabs, quotes, and backslashes:
❯ echo "${str#Q}"
$'\nHello\nWorld\n'
❯ printf '%q\n' "$str"
$'\nHello\nWorld\n'
Alternatively, if you simply want to replace newlines and nothing else you can use ${var//search/replace} syntax to do replacements:
❯ echo "${str//$'\n'/\\n}"
\nHello\nWorld\n
Try:
sed -zn 's/\n/\\n/p' <<< "$str"
Use -z to consume the variable as one line and substitute new lines for literal newlines.
this is perhaps one of the most discussed topics here. I tried almost all the commands and other tweaks found here, but something doesn't seems to be doing well.
i would want to replace all the double quotes in my file with whitespace/blank
I'm seeing the below error when i tried to execute this command.
sed "s/"/ \''/g' x_orbit.txt > new.tx
sed: -e expression #1, char 3: unterminated `s' command
You're close. Just use single quotes, so the shell doesn't try to expand the metacharacters in your sed command:
sed 's/"/ /g' x_orbit.txt > new.txt
You could try tr for example:
tr '"' ' ' < x_orbit.txt > new.txt
The script you provided:
sed "s/"/ \''/g' x_orbit.txt > new.tx
means:
sed # invoke sed to execute the following script:
" # enclose the script in double quotes rather than single so the shell can
# interpret it (e.g. to expand variables like $HOME) before sed gets to
# interpret the result of that expansion
s/ # replace what follows until the next /
" # exit the double quotes so the shell can now not only expand variables
# but can now do globbing and file name expansion on wildcards like foo*
/ # end the definition of the regexp you want to replace so it is null since
# after the shell expansion there was no text for sed to read between
# this / and the previous one (the 2 regexp delimiters)
\' # provide a blank then an escaped single quote for the shell to interpret for some reason
'/g' # enclose the /g in single quotes as all scripts should be quoted by default.
That is so far off the correct syntax it's kinda shocking which is why I dissected it above to try to help you understand what you wrote so you'll see why it doesn't work. Where did you get the idea to write it that way (or to put it another way - what did you think each character in that script meant? I'm asking as it indicates a fundamental misunderstanding of how quoting and escaping works in shell so it'd be good if we could help correct that misunderstanding rather than just correct that script.
When you use any script or string in shell, simply always enclose it in single quotes:
sed 'script' file
var='string'
unless you NEED to use double quotes to let a variable expand and then use double quotes unless you NEED to use no quotes to let globbing and file name expansion happen.
An awk version:
awk '{gsub(/"/," ")}1' file
gsub is used for the replace
1 is always true, so line is printed
I'm trying to use a variable in a grep regex. I'll just post an example of the failure and maybe someone can suggest how to make the variable be evaluated while running the grep command. I've tried ${var} as well.
$ string="test this"
$ var="test"
$ echo $string | grep '^$var'
$
Since my regex should match lines which start with "test", it should print the line echoed thru it.
$ echo $string
test this
$
You need to use double quotes. Single quotes prevent the shell variable from being interpolated by the shell. You use single quotes to prevent the shell from doing interpolation which you may have to do if your regular expression used $ as part of the pattern. You can also use a backslash to quote a $ if you're using double quotes.
Also, you may need to put your variable in curly braces ${var} in order to help separate it from the rest of the pattern.
Example:
$ string="test this"
$ var="test"
$ echo $string | grep "^${var}"
I need to find some special characters in a given input string .
If the string contains following special characters it should find out.
i am doing egrep to find the characters.
My code is working for every character but not single quotes.
please find my code snippet.
splCharCheck='egrep "&|\"|:|\'" | wc -l'
count=`echo "$Name" | eval $splCharCheck`
Can any one help me how to escape single quotes here?
Don't "escape" the single quote. Check below:
# cat test
'name with quotes'
no quotes
# cat test | egrep "'"
'name with quotes'
# cat test | egrep "\'"
'name with quotes'
no quotes
What are you trying to achieve? This smells like an XY problem.
In bash you can escape text easily using
printf "%q\n" "$Name"
E.g.:
$ Name="Some 'intricate' value"
$ printf "%q\n" "$Name"
Some\ \'intricate\'\ value
You're trying to embed a single-quote inside a double-quoted string which is inside a single-quoted string. The problem is that inside the single-quoted string, the double-quotes aren't treated as anything special, so the single-quote in the middle gets treated as the end of the single-quoted string rather than a part of it. In order to do this, you need to end the single-quoted string ('egrep "&|\"|:|'), escape the lone single-quote some other way (either \' or "'"), then start a new single-quoted string with the rest of what you want ('" | wc -l'). End result:
splCharCheck='egrep "&|\"|:|'\''" | wc -l'
However, I have to agree with #sehe that it looks like you're trying to solve the wrong problem. Why are you putting this command in a variable rather than executing it directly? That's generally a bad idea (and eval just adds more opportunities for things to get weird). And, backing up even further, what are you really trying to do?
p.s. If you must use eval, at least double-quote the string your're eval'ing. Failing to do this can lead to some seriously incomprehensible errors. Finally, I recommend using $( ) instead of backquotes, since it has fewer parsing oddities:
count=$(echo "$Name" | eval "$splCharCheck")
I would like to set a variable in bash called test_var
Basically, I want echo test_var to output:
%let output="file_20120601.csv";
where 20120601 is a variable. I am trying to do this by using:
test_var='%let output="file_$1.csv";'
echo test_var
this doesn't work because $1 is not interpreted as variable, but interpreted as literally $1
Does anybody know how I can modify this to get it to do what I want it to do?
It doesn't work because of single quotes. They make everything literal.
$ var='123'
$ foo="\"%hi there file_$var\""
$ echo $foo
"%hi there file_123"
this works too
test_var='%let output="file_'"$1"'.csv";'
because variables are not expanded between single quotes.
and we can concatenate strings between single quotes and double quotes just writing strings beside.