unexpected EOF while looking for matching `"' unexpected end of file - shell

I have a string
str="xx:mvt="this is the value""
While executing above string in a command( command $str ). Command is not accepting 'this is the value' as one value.
How to do this?
I wanted to replace ' character with \" to interpret special character. below is the code but getting above exception:
str=`sed "s/\"/\\\"/g" <<< "$str"`

The assign should be in form:
str='xx:mvt="this is the value"'
This will keep double quotes and assign string xx:mvt="this is the value" to the variable
Also the command (with sed) must be like:
str=`sed 's/\"/\\\"/g' <<< "$str"`

Related

How to expend a variable with a quote, on the quote?

Given the following string:
toto="function(param"
I want to get the substring function from the string above, in bash.
I tried the following:
echo "${toto%(}"
Which gives:
function(param
However, with this example:
echo "${toto%param}"
I get:
function(
As expected.
The expansion did not take place when expanding the the character "(".
Why is that ? How can I extract only the beginning (before the "(" of this string ?
To cut ( and anything after it you have match exactly that.
echo "${toto%(*}"

Using sed with a substitution variable that may have curly braces

I'm writing a script for looping over a set of files in a directory searching for a string (stringA) in one file (srcFile), copying the line that follows it (stringToCopy), and pasting it on the line after another search string (stringB) in another file (outputFile). The copy/paste script that I have so far is as follows
stringA="This is string A"
stringB="This is string B"
srcFile=srcFile.txt
outpuFile=outputFile.txt
replacement="/$stringA/{getline; print}"
stringToCopy="$(awk "$replacement" $srcFile)"
sed -i "/$stringB/!b;n;c${stringToCopy}" $outputFile
The script works great, except when stringToCopy ends up containing curly braces. Example is
srcFile.txt:
This is string A
text to copy: {0}
outputFile.txt:
This is string B
line to be replaced
Once the script is done, I would expect outputFile.txt to be
This is string B
text to copy: {0}
But sed chokes with
sed: -e expression #1, char 106: unknown command: `m'
I've tried hardcoding the problematic string and trying different variations of escaping the curlies and quoting the string, but haven't found a winning combination and I'm at a loss for how to make it work.
EDIT
I had a derp moment and forgot that my stringA also has curly braces, that happened to cause my awk command to math multiple lines. This caused my stringToCopy to have newlines in it which is my real issue, not the curly braces. So the real question is, how to make awk treat curly braces as literal characters so that
srcFile.txt
This is string A: {0}
text to copy: {0}
This is string A:
Other junk
And stringA="This is string A: {0}"
Doesn't set stringToCopy to
text to copy: {0}
Other junk
A bit of a kludge in that we're going to add some extra coding specifically for braces ...
Current situation:
$ awk '/This is string A: {0}/{getline; print}' srcFile.txt
text to copy: {0} # this is the line we want
Other junk # we do not want this line
We can eliminate the second line by escaping the braces in the search pattern, eg:
$ awk '/This is string A: \{0\}/{getline; print}' srcFile.txt
text to copy: {0}
So, how to escape the braces? We can use some explicit parameter expansions to replace the braces with escaped braces in the $stringA variable, keeping in mind that we also need to escape the braces in the parameter expansion phase, too:
$ stringA="This is string A: {0}"
$ stringA="${stringA//\{/\\{}" # replace '{' with '\{'
$ stringA="${stringA//\}/\\}}" # replace '}' with '\}'
$ echo "${stringA}"
This is string A: \{0\}
We can then proceed with the rest of the code as is:
$ replacement="/$stringA/{getline; print}"
$ echo "${replacement}"
/This is string A: \{0\}/{getline; print}
$ stringToCopy="$(awk "$replacement" $srcFile)"
$ echo "${stringToCopy}"
text to copy: {0}
As for the final sed step I had to remove the ! to get it to work correctly:
$ sed -i "/$stringB/b;n;c${stringToCopy}" $outputFile
$ cat "${outputFile}"
This is string B
text to copy: {0}
NOTES:
if you preface your coding with set -xv you can see how variables are being interpreted at each step; use set +xv to turn off
obviously you'll probably run into issues if you do in fact have more than 1 matching row in $srcFile
if you find other characters that need to be escaped then you'll need to add additional parameter expansions for said characters

Ruby: How to insert three backslashes into a string?

I want to use backticks in ruby for a programm call.
The parameter is a String variable containing one or more backticks, i.e.
"&E?##A`?". The following command yields a new label as its return value:
echo "&E?##A\`?" | nauty-labelg 2>/dev/null
From a ruby program I can call it as follows and get the correct result:
new_label = `echo "&E?##A\\\`?" | nauty-labelg 2>/dev/null`
I want to achieve the same using a variable for the label.
So I have to insert three slashes into my variable label = "&E?##A`?" in order to escape the backtick. The following seems to work, though it is not very elegant:
escaped_label = label.gsub(/`/, '\\\`').gsub(/`/, '\\\`').gsub(/`/, '\\\`')
But the new variable cannot be used in the program call:
new_label = `echo "#{escaped_label}" | nauty-labelg 2>/dev/null`
In this case I do not get an answer from nauty-labelg.
So I have to insert three slashes into my variable label = "&E?##A`?" in order to escape the backtick.
No, you only need to add one backslash for the output. To escape the ` special bash character. The other other two are only for representation proposes, otherwise it isn't valid Ruby code.
new_label = `echo "&E?##A\\\`?" | nauty-labelg 2>/dev/null`
The first backslash will escape the second one (outputting one single backslash). The third backslash escapes the ` character (outputting one single `).
You should only add backslashes before characters that have a special meaning within double quoted bash context. These special characters are: $, `, \ and \n. Those can be escaped with the following code:
def escape_bash_string(string)
string.gsub(/([$`"\\\n])/, '\\\\\1')
end
For label = "&E?##A`?" only the ` should be escaped.
escaped_string = escape_bash_string("&E?##A\`?")
puts escaped_string
# &E?##A\`?

Bash: syntax error in expression (error token is ...)

This line in a bash file has been working for six months:
SCRATCH_FOLDER_NAME="${SCRATCH_FOLDER_NAME:scratch--folder}"
and today it decided to be no more, with this error:
SCRATCH_FOLDER_NAME: scratch--folder: syntax error in expression (error token is "folder")
What does it mean?
For reference, here is the complete script:
#!/bin/bash
SHIMMERCAT_SCRATCH_FOLDER_NAME="${SHIMMERCAT_SCRATCH_FOLDER_NAME:shimmercat-scratch--folder}"
REDIS_UNIX_SOCKET="/unpriv/$SHIMMERCAT_SCRATCH_FOLDER_NAME/redis.sock"
if [[ -z ${DONT_RUN_REDIS+x} ]]; then
chown shimmercat:shimmercat $SHIMMERCAT_SCRATCH_FOLDER_NAME
...
fi
"${SCRATCH_FOLDER_NAME:scratch--folder}" is not a correct parameter expansion. Consider the following, where comma is the delimiter:
# Get string before first matching delimeter
${var%%,*}
# Get string before last matching delimeter
${var%,*}
# Get string after first matching delimeter
${var#*,}
# Get string after last matching delimeter
${var##*,}
As for how it worked I am not sure. Here is a good reference for the different types of parameter expansions.

unexpected EOF while looking for matching `'' while using sed

Yes this question has been asked many times, and in the answer it is said to us \ escape character before the single quote.
In the below code it isn't working:
LIST="(96634,IV14075295,TR14075685')"
LIST=`echo $LIST | sed 's/,/AAA/g' `
echo $LIST # Output: (96634AAAIV14075295AAATR14075685')
# Now i want to quote the list elements
LIST=`echo $LIST | sed 's/,/\',\'/g' ` # Giving error
# exit 0
Error :
line 7: unexpected EOF while looking for matching `''
line 8: syntax error: unexpected end of file
Instead of single quotes, use double quotes in sed command, and also remove the space before last backtick. If there is single quote present in the sed pattern then use an alternative enclosing quotes(ie, double quotes),
sed "s/,/\',\'/g"
And the line would be,
LIST=$(echo $LIST | sed "s/,/\',\'/g")
Don't use backticks inside the sripts instead of bacticks, use $()
You can use awk
echo $LIST
(96634,IV14075295,TR14075685')
LIST=$(awk '{gsub(/,/,q"&"q)};gsub(/\(/,"&"q)1' q="'" <<< $LIST)
echo $LIST
('96634','IV14075295','TR14075685')
To prevent problems with the single quote, I just set it to an awk variable.
consider
LIST="$(sed "s/,/\',\'/g" <<< "$LIST")"
but first and last elements probably won't get quoted completely, because of missing leading and trailing comma
btw, you don't need to subshell to sed - string matching and substitution is entirely within the capabilities of bash:
LIST="${LIST//,/\',\'}"

Resources