I want to something like this in bash:
alias foo='bar="$(echo hello world | grep \"hello world\")"; echo $bar;'; foo
Expected output: hello world
Ouput: grep: world": No such file or directory
The outer quotes have to be single quotes, with double quotes $bar would be empty.
The next quotes have to be double quotes, with single quotes $() wouldn't expand.
The inner quotes could be both type of quotes, but single quotes doesn't allow single quotes inside of them.
How to I achieve this?
The stuff inside $() represents a subshell, so you are allowed to place un-escaped double quotes inside
alias foo='bar="$(echo testing hello world | grep "hello world")"; echo "$bar"'
It's a bit unclear what "something like this" means, but the simplest way to achieve what seems to be the point here is a simple function:
foo() {
echo 'hello world' | grep 'hello world'
}
foo
There's no need for an intermediate variable assignment (it will be lost anyway).
Functions are generally preferred over aliases because of more flexibility (parameter handling) and readability (multiple lines; less escaping).
Always use the simplest solution which could possibly work.
Escape the spaces
alias foo='bar="$(echo hello world | grep hello\ world)"; echo $bar;'
The double quotes around $() are not necessary:
alias foo='bar=$(echo hello world | grep "hello world"); echo $bar;'
foo
# Output:
hello world
Related
I am trying to escape backtick in bash for long time.
I tried escaping with \ but it does not work.
Is it possible to escape backtick in bash?
Sample code
I="hello.pdf"
var1=`cat <<EOL
![](../images/${I%.*}.png)
\`\`\`sql
some code here
\`\`\`
EOL`
echo "$var1"
Required output
![](../images/hello.png)
```sql
some code here
```
Use $(...) instead of backtick syntax for the outer command substitution. Thus:
I='foo.png'
var1=$(cat <<EOL
![](../images/${I%.*}.png)
\`\`\`sql
some code here
\`\`\`
EOL
)
echo "$var1"
See this running, and emitting your desired output, at https://ideone.com/nbOrIu
Otherwise, you need more backslashes:
I='foo.png'
var1=`cat <<EOL
![](../images/${I%.*}.png)
\\\`\\\`\\\`sql
some code here
\\\`\\\`\\\`
EOL
`
echo "$var1"
...and if you were to nest backticks inside backticks, you'd need to multiply your backslashes yet again. Just Say No to backtick-based command substitution.
By the way, something you might consider to evade this problem altogether:
I='foo.png'
fence='```'
var1=$(cat <<EOL
![](../images/${I%.*}.png)
${fence}sql
some code here
${fence}
EOL
)
echo "$var1"
...putting the literal backticks in a variable means you no longer need any kind of escaping to prevent them from being treated as syntax.
The question is basically, how does bash deal with double quotes and brackets?
I couldn't come up with a better example, so apologies about that, but imagine something like this:
"$(echo "${foo}")"
What happens there? Is ${foo} technically out of the quotation scope? Is bash smart enough to also consider that it is inside of the parentheses and work inside-out? Would \"${foo}\" work better?
I've tried Googling this, but no luck. Please note that this is different from just nested quoting questions, as it includes expansion.
Thanks!
Each command substitution establishes a new quoting context, so the correct way to avoid word splitting inside nested command substitutions is to use double quotes.
In this example, white space is preserved:
$ echo "$(echo "$(echo 'foo bar')")" # outer echo sees 'foo bar'
foo bar
However, missing any of the double quotes means that the string is split by the shell:
$ echo $(echo "$(echo 'foo bar')") # outer echo sees 'foo' 'bar'
foo bar
$ echo "$(echo $(echo 'foo bar'))" # middle echo sees 'foo' 'bar'
foo bar
echo outputs each argument, separated by a spaces, which is where the single space between "foo" and "bar" comes from.
The example you gave does save you from word splitting completely:
"$(echo "${foo}")"
while,
"$(echo ${foo})"
would save you from word splitting on the output but not on the variable $foo.
$() opens a subshell and you need to quote your vars in this subshell too. Consider the following example:
"$(echo "$(echo "$foo")")"
None of the pair of quotes above is optional, if you miss any of them, you will be subject to word splitting.
Consider another example:
"$foo var in same shell, $(cmd) - this output is also in the same shell"
In above, $foo and the output of cmd are safe, but if the cmd includes another variable inside $(), then that variable will need to be quoted.
What is foo? Is it a value? try
"$(echo "$\{foo\}")"
Whenever im trying to insert output with a line break into a variable for instance like this:
Hello
World
Once i do an echo command on the variable i get this:
"Hello World"
Why does it happen and how can i
keep the line break?
In bash, the easiest way to express a literal line break is with $'' syntax:
var=$'Hello\nWorld'
echo "$var"
Note that the quotes around $var are mandatory during expansion if you want to preserve linebreaks or other whitespace! If you only run
echo $var
...then even though a linebreak is stored in your variable, you will see
Hello World
on a single line, as opposed to
Hello
World
on two lines.
This happens because when you don't use quotes, the shell splits the expanded words on whitespace -- including newlines -- and passes each item created by that split as a separate argument. Thus,
echo "$var"
will pass a single string with the entire expansion of $var, whereas
echo $var
will run the equivalent of:
echo "Hello" "World"
...passing each word in the text as a separate argument to echo (whereafter the echo command re-joins its arguments by spaces, resulting in the behavior described).
Line breaks can be embedded in a string in any POSIX compatible shell:
$ str="Hello
> World"
$ echo "$str"
Hello
World
If you hit enter before closing the quotation marks, the shell knows you have not yet finished the quoted material, and prints the secondary prompt (>) and waits for you to finish the command.
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")