bash: assign punctuation to variable - bash

when I assign like this:
rmall="\,\.\?\!\:\;\(\)\[\]\{\}\"\'"
then echo $rmall, I got this:
\,\.\?\!\:\;\(\)\[\]\{\}\"\'
But what I want is only , How can I do?
,.?!:;()[]{}"'
as later I need to remove those.
Thank you

You are double quoting by using quotes and backslashes. Use one or the other.
Note: You will always need to use backslash for escaping your quote character but otherwise not needed.

Inside double quotes, only three escape sequences are treated specially:
\" is replaced by a literal "
\$ is replaced by a literal $
\\ is replaced by a literal \
These three are required to allow the literal character in contexts where they would normally produce special behavior. \", obviously, lets you include a double-quote inside a double-quoted string. \$ lets you output a literal dollar sign where it would otherwise trigger parameter substitution:
bash $ foo=5; echo "\$foo = $foo"
$foo = 5
\\ lets you output a literal backslash that precedes a parameter substitution or at the end of a string.
bash $ foo=5; echo "\\$foo"
\5
bash $ echo "Use a \\"
Use a \
A backslash followed by any other character is treated literally:
bash $ echo "\x"
\x

Related

su -c <user> command fails in shell script [duplicate]

In Bash, what are the differences between single quotes ('') and double quotes ("")?
Single quotes won't interpolate anything, but double quotes will. For example: variables, backticks, certain \ escapes, etc.
Example:
$ echo "$(echo "upg")"
upg
$ echo '$(echo "upg")'
$(echo "upg")
The Bash manual has this to say:
3.1.2.2 Single Quotes
Enclosing characters in single quotes (') preserves the literal value of each character within the quotes. A single quote may not occur between single quotes, even when preceded by a backslash.
3.1.2.3 Double Quotes
Enclosing characters in double quotes (") preserves the literal value of all characters within the quotes, with the exception of $, `, \, and, when history expansion is enabled, !. The characters $ and ` retain their special meaning within double quotes (see Shell Expansions). The backslash retains its special meaning only when followed by one of the following characters: $, `, ", \, or newline. Within double quotes, backslashes that are followed by one of these characters are removed. Backslashes preceding characters without a special meaning are left unmodified. A double quote may be quoted within double quotes by preceding it with a backslash. If enabled, history expansion will be performed unless an ! appearing in double quotes is escaped using a backslash. The backslash preceding the ! is not removed.
The special parameters * and # have special meaning when in double quotes (see Shell Parameter Expansion).
The accepted answer is great. I am making a table that helps in quick comprehension of the topic. The explanation involves a simple variable a as well as an indexed array arr.
If we set
a=apple # a simple variable
arr=(apple) # an indexed array with a single element
and then echo the expression in the second column, we would get the result / behavior shown in the third column. The fourth column explains the behavior.
#
Expression
Result
Comments
1
"$a"
apple
variables are expanded inside ""
2
'$a'
$a
variables are not expanded inside ''
3
"'$a'"
'apple'
'' has no special meaning inside ""
4
'"$a"'
"$a"
"" is treated literally inside ''
5
'\''
invalid
can not escape a ' within ''; use "'" or $'\'' (ANSI-C quoting)
6
"red$arocks"
red
$arocks does not expand $a; use ${a}rocks to preserve $a
7
"redapple$"
redapple$
$ followed by no variable name evaluates to $
8
'\"'
\"
\ has no special meaning inside ''
9
"\'"
\'
\' is interpreted inside "" but has no significance for '
10
"\""
"
\" is interpreted inside ""
11
"*"
*
glob does not work inside "" or ''
12
"\t\n"
\t\n
\t and \n have no special meaning inside "" or ''; use ANSI-C quoting
13
"`echo hi`"
hi
`` and $() are evaluated inside "" (backquotes are retained in actual output)
14
'`echo hi`'
`echo hi`
`` and $() are not evaluated inside '' (backquotes are retained in actual output)
15
'${arr[0]}'
${arr[0]}
array access not possible inside ''
16
"${arr[0]}"
apple
array access works inside ""
17
$'$a\''
$a'
single quotes can be escaped inside ANSI-C quoting
18
"$'\t'"
$'\t'
ANSI-C quoting is not interpreted inside ""
19
'!cmd'
!cmd
history expansion character '!' is ignored inside ''
20
"!cmd"
cmd args
expands to the most recent command matching "cmd"
21
$'!cmd'
!cmd
history expansion character '!' is ignored inside ANSI-C quotes
See also:
ANSI-C quoting with $'' - GNU Bash Manual
Locale translation with $"" - GNU Bash Manual
A three-point formula for quotes
If you're referring to what happens when you echo something, the single quotes will literally echo what you have between them, while the double quotes will evaluate variables between them and output the value of the variable.
For example, this
#!/bin/sh
MYVAR=sometext
echo "double quotes gives you $MYVAR"
echo 'single quotes gives you $MYVAR'
will give this:
double quotes gives you sometext
single quotes gives you $MYVAR
Others explained it very well, and I just want to give something with simple examples.
Single quotes can be used around text to prevent the shell from interpreting any special characters. Dollar signs, spaces, ampersands, asterisks and other special characters are all ignored when enclosed within single quotes.
echo 'All sorts of things are ignored in single quotes, like $ & * ; |.'
It will give this:
All sorts of things are ignored in single quotes, like $ & * ; |.
The only thing that cannot be put within single quotes is a single quote.
Double quotes act similarly to single quotes, except double quotes still allow the shell to interpret dollar signs, back quotes and backslashes. It is already known that backslashes prevent a single special character from being interpreted. This can be useful within double quotes if a dollar sign needs to be used as text instead of for a variable. It also allows double quotes to be escaped so they are not interpreted as the end of a quoted string.
echo "Here's how we can use single ' and double \" quotes within double quotes"
It will give this:
Here's how we can use single ' and double " quotes within double quotes
It may also be noticed that the apostrophe, which would otherwise be interpreted as the beginning of a quoted string, is ignored within double quotes. Variables, however, are interpreted and substituted with their values within double quotes.
echo "The current Oracle SID is $ORACLE_SID"
It will give this:
The current Oracle SID is test
Back quotes are wholly unlike single or double quotes. Instead of being used to prevent the interpretation of special characters, back quotes actually force the execution of the commands they enclose. After the enclosed commands are executed, their output is substituted in place of the back quotes in the original line. This will be clearer with an example.
today=`date '+%A, %B %d, %Y'`
echo $today
It will give this:
Monday, September 28, 2015
Since this is the de facto answer when dealing with quotes in Bash, I'll add upon one more point missed in the answers above, when dealing with the arithmetic operators in the shell.
The Bash shell supports two ways to do arithmetic operation, one defined by the built-in let command and the other the $((..)) operator. The former evaluates an arithmetic expression while the latter is more of a compound statement.
It is important to understand that the arithmetic expression used with let undergoes word-splitting, pathname expansion just like any other shell commands. So proper quoting and escaping need to be done.
See this example when using let:
let 'foo = 2 + 1'
echo $foo
3
Using single quotes here is absolutely fine here, as there isn't any need for variable expansions here. Consider a case of
bar=1
let 'foo = $bar + 1'
It would fail miserably, as the $bar under single quotes would not expand and needs to be double-quoted as
let 'foo = '"$bar"' + 1'
This should be one of the reasons, the $((..)) should always be considered over using let. Because inside it, the contents aren't subject to word-splitting. The previous example using let can be simply written as
(( bar=1, foo = bar + 1 ))
Always remember to use $((..)) without single quotes
Though the $((..)) can be used with double quotes, there isn't any purpose to it as the result of it cannot contain content that would need the double quote. Just ensure it is not single quoted.
printf '%d\n' '$((1+1))'
-bash: printf: $((1+1)): invalid number
printf '%d\n' $((1+1))
2
printf '%d\n' "$((1+1))"
2
Maybe in some special cases of using the $((..)) operator inside a single quoted string, you need to interpolate quotes in a way that the operator either is left unquoted or under double quotes. E.g., consider a case, when you are tying to use the operator inside a curl statement to pass a counter every time a request is made, do
curl http://myurl.com --data-binary '{"requestCounter":'"$((reqcnt++))"'}'
Notice the use of nested double quotes inside, without which the literal string $((reqcnt++)) is passed to the requestCounter field.
There is a clear distinction between the usage of ' ' and " ".
When ' ' is used around anything, there is no "transformation or translation" done. It is printed as it is.
With " ", whatever it surrounds, is "translated or transformed" into its value.
By translation/ transformation I mean the following:
Anything within the single quotes will not be "translated" to their values. They will be taken as they are inside quotes. Example: a=23, then echo '$a' will produce $a on standard output. Whereas echo "$a" will produce 23 on standard output.
A minimal answer is needed for people to get going without spending a lot of time as I had to.
The following is, surprisingly (to those looking for an answer), a complete command:
$ echo '\'
whose output is:
\
Backslashes, surprisingly to even long-time users of bash, do not have any meaning inside single quotes. Nor does anything else.

How does escape character work in bash quote?

Reading through Escape Character and Quotes sections
For escape character "", It mentions that
It preserves the literal value of the next character that follows
For sigle quote
' preserves the literal value of each character within the quotes
echo 'a\\nb'
> a\nb
echo 'a\\\nb'
> a\
> b
Questions are:
Why \ is not interpretated as its literal meaning, instead 2 backslash is interpretated as one \ here ?
2.1 Are all the sequence in ANSI c standard reserved as a single character ?
2.2 But following example seems contradicating to the above assumption.
echo '\"'
> \" # instead of printing ", it prints \"
The ANSI escape sequences are interpreted by the shell, only if you wrap them around $'..' and not otherwise
In the case of 'a\\nb' without the ANSI sequences, it is treated literally as characters a, followed by two \, n and b. Only within the ANSI quoting syntax it is treated special, i.e. in $'a\\nb', the \n is interpreted as special sequence for a newline character, but that expansion is deferred because of the additional escape which prevents the \n from being expanded, making it expanded literally.
echo 'a\\nb'
a\\nb
echo $'a\\nb'
a\nb
The case of 'a\\\nb' is the same, without the ANSI escapes, the content is expanded literally, but with the presence of quotes, the sequence a\\\nb is interpreted by the shell to be having one escape character for \ as \\ and one \n, so it expands to
echo $'a\\\nb'
a\
b
Yes, the ANSI escape sequences are treated as a single character when the shell expands it.
And there is no escape sequence expansion involved in '\"', with the presence of single quotes the content within is preserved literally
echo '\"'
\"
echo '"'
"
Note that with ANSI quoting for the above case the $'..' is expanded, expanding any potential escape sequences, so \" expands to just "
echo $'\"'
"
Reference - ANSI-C Quoting
Between the ' ' quotes there is no interpretation of escape sequences. Write
"\""
and you get the expected behavior.

bash printf: How do I output \x and \f within double quotes?

I am trying to printf an input with variables and need double quotes. My output needs a \x and \f text output.
printf "\x"
or
printf "\\x"
produces the error:
./pegrep.in: line 94: printf: missing hex digit for \x
while
printf "\f"
or
printf "\\f"
produces nothing at all (in a text output I believe it creates ^L)
single quotes however works for x (but not f). I tried enclosing
printf "...'\\x'..."
and got the same error as standard double quotes. Have also tried /// to no avail.
First, let's understand how quoting works.
The simplest form of quoting is the backslash: it prevents the following character from being interpreted in any special way, allowing it to be used as a literal character. For example:
# Two arguments to printf
$ printf '%s\n' a b
a
b
# One three-character argument to printf
printf '%s\n' a\ b
a b
Double quotes are equivalent to escaping every character contained therein: "a b c" is equivalent to \a\ \b\ \c, which is the same as a\ b\ c because a, b, and c have no special meaning to begin with. You can think of every character inside double quotes as being treated literally, with the following exceptions:
$ can start a parameter expansion or a command substitution. Escape it with a backslash to treat it literally.
$ foo=3
$ echo "$foo"
3
$ echo "\$foo"
$foo
A backquote starts a command substitution. Escape it with a backslash to treat it literally.
$ echo "`pwd`"
/home/me
$ echo "\`pwd\`"
`pwd`
A double quote ends a quoted string. Escape it with a backslash to treat it literally.
$ echo "\""
"
Because a backslash might be part of one of the three preceding sequences, escape it with a backslash to treat one literally.
$ echo "\\"
\
Inside single quotes, everything is treated literally, including any use of a backslash. (One consequence of this is that it is impossible to put a single quote in a single-quoted string, because it will always terminate such a string.)
$ echo '\'
\
Once you understand quoting, you next need to realize that printf itself can process whatever backslashes it sees in its first argument.
$ printf 'a\x20b\n' # a, space (ASCII 0x20), b, newline
a b
In order to ensure a string is printed literally no matter what characters are present, use the %s format specifier and pass your string as a second argument:
$ printf '\x41\n'
A
$ printf '%s\n' '\x41'
\x41
I think you may be confusing the \ and the % characters. The % is used to output formatted variable contents. I think this when \f is outputs ^L (aka ASCII FF) that escape sequence is working as documented.
The printf argument can be quoted with single quotes. Then you can use double quotes within it and they will be part of the output:
printf '"%x"' 4011 # output: "fab"
Similarly for floating point:
print '"%f"' 2.2 # output: "2.200000"
The \ character is for escape sequences of otherwise unprintable characters.
See man printf for a full list of the % format characters and their meanings.

How to escape characters from a single command?

How do I escape characters in linux using the sed command?
I want to print something like this
echo hey$ya
But I'm just receiving a
hey
how can escape the $ character?
The reason you are only seing "hey" echoed is that because of the $, the shell tries to expand a variable called ya. Since no such variable exists, it expands to an empty string (basically it disappears).
You can use single quotes, they prevent variable expansion :
echo 'hey$ya'
You can also escape the character :
echo hey\$ya
Strings can also be enclosed in double quotes (e.g. echo "hey$ya"), but these do not prevent expansion, all they do is keep the whole expression as a single string instead of allowing word splitting to separate words in separate arguments for the command being executed. Using double quotes would not work in your case.
\ is the escape character. So your example would be:
~ » echo hey\$ya
hey$ya
~ »

Must special characters in bash double quoted or escaped with \

Should I double quote or escape with \ special characters like ',
$ echo "'"
'
$ echo \'
'
Here is apparently doesn't matter, but are there situations where there is a difference, except for $, `` or`, when I know there is a difference.
Thanks,
Eric J.
You can use either backslashes, single quotes, or (on occasion) double quotes.
Single quotes suppress the replacement of environment variables, and all special character expansions. However, a single quote character cannot be inside single quotes -- even when preceded by a backslash. You can include double quotes:
$ echo -e 'The variable is called "$FOO".'
The variable is called "$FOO".
Double quotes hide the glob expansion characters from the shell (* and ?), but it will interpolate shell variables. If you use echo -e or set shopt -s xpg_echo, the double quotes will allow the interpolation of backslash-escaped character sequences such as \a, and \t. To escape those, you have to backslash-escape the backslash:
$ echo -e "The \\t character sequence represents a tab character."
The \t character sequence represents a tab character."
The backslash character will prevent the expansion of special characters including double quotes and the $ sign:
$ echo -e "The variable is called \"\$FOO\"."
The variable is called "$FOO".
So, which one to choose? Which everyone looks the best. For example, in the preceding echo command, I would have been better off using single quotes and that way I wouldn't have the confusing array of backslashes one right after another.
On the other hand:
$ echo -e "The value of \$FOO is '$FOO'."
The value of FOO is 'bar'.
is probably better than trying something like this:
$ echo -e 'The value of $FOO is '"'$FOO'."
Readability should be the key.

Resources