How to expand correctly a variable in sed command - bash

I have this file:
user0:
hash: $2a$12$DA47ZutoC.89KDePyBK.yubz.2vfEiLi28ENBRuyoNf.px3.vHINq
user1:
hash: $2a$12$Auk82xqdbgFb4AJKyvSuWOKTQivuHhJZwckLii5/a5ILhCke0sddS
user3:
hash: $2a$12$QW/dCK7CqE5s87OIk8QBeeBYVvD5tjbd46jH9wVD9YMWW31KQEA1y
user4:
hash: $2a$12$60ds1ivJzM/DexIBYUilzO4BPjumsdTOETAHoopIxabffoWiDEkum
and a bash script to change the hash associated to a username.
For example to change user1 hash, i would use:
sed -i "/user1:/{n;s,.*, hash: NEW_HASH/}" MY_FILE
Now, in the script I have variables, and so actually my previous example is:
sed -i "/$1:/{n;s,.*, hash: $hash/}" "$users"
My problem is that the $hash parameter has got also / characters, resulting in a sed error like this:
sed: -e expression #1, char 85: unterminated `s' command
How to correct my command in order to let it expand hash variable correctly? I tried some combinations of ' and " commands but without results. Any help?
Thank you!

Since you are using , as the delimiter for the s command it should be:
sed -i "/$1:/{n;s,.*, hash: $hash,;}" "$users"
----------------------------------^ comma, not /
I've also appended a ; after the s command. Some implementations of sed need that.

Related

Not able to add a line of text after pattern using sed in OSX

I'm trying to add a line in a file afile.xyz using my script. This is what I've done so far using sed:
n="$(grep ".method" "$m" | grep "onCreate(Landroid/os/Bundle;)V")"
sed -i '' -e '/$n/ a\
"test", /Users/username/Documents/afile.xyz
I'm getting the error:
"onCreate\(\Landroid\/ ...": bad flag in substitute command: 'g'
How do I solve this? Please do help. Thanks.
Edit: Content of n
method protected onCreate(Landroid/os/Bundle;)V
2 problems:
because the sed body is in single quotes, the variable $n will not be expanded,
the regular expression in $n contains the / dilimiters.
Try this:
n=$(...)
nn=${n//\//\\/} # escape all slashes
sed -i '' '/'"${nn}"'/ a ...
The single-quoted sed body is interrupted to append the double quoted shell variable.
You can also use a different delimiter for the RE:
sed -i '' -e "\#$n# a\\
\"test\"" /Users/username/Documents/afile.xyz

pass dynamic value in the sed command in unix inside IT block ruby

output.txt:
select * from table startTime.... (very big query)
abc.rb:
it "example" do
time = 6537290102
replacestarttime = `sed -i -e 's/startTime/$time/g' ./db/output.txt`
end
expected output----
output.txt:
select * from table 6537290102....
In output.txt, the value should be 6537290102 please someone help. thanks in advance
If I hardcode the time value as shown below in sed command then it is working fine whereas the passing the dynamic value "time" is not working
replacestarttime = sed -i -e 's/startTime/6537290102/g' ./db/output.txt
Replace single quotes with double quotes
`sed -i -e "s/startTime/$time/g" ./db/output.txt`
Interpolate Your String in Ruby
Right now, you're expecting sed to access a shell variable named $time. This variable doesn't exist, and wouldn't work as-is even if it did.
To fix this, you should to interpolate your Ruby variable into the string passed to sed. You can do this as follows:
it "example" do
time = 6537290102
replacestarttime = `sed -i -e 's/startTime/#{time}/g' ./db/output.txt`
end

Concatenation String in shell

I have this shell line to concatenate 2 string:
new_group="second result is: ${result},\"${policyActivite}_${policyApplication}\""
echo "result is: ${new_group}"
The result:
result is: "Team","Application_Team"
How can change the result to: result is: "Team, Application_Team"
Use sed:
echo "$new_group" | sed 's/"//g;s/^\(.*\)$/"\1"/'
The first statement is removing all double quotes. The second one add double at the start and the end of the line.
Alternatively, if you want to replace "," with ,, use this sed command: sed 's/","/, /g'

Unable to define line number in sed by variable

I'm trying to use an array to define the lines to replace using sed; I can delete the lines using a variable for the line number but I can't get sed to use the variable to define the line number to write to. The problem seems to reside in the insert line. How do you pass the value of an array as a line number to sed?
#!/bin/bash
lineNum=$(sed -n '/max_allowed_packet/=' /etc/mysql/my.cnf)
IFS= #There's a space as the delimiter#
ary=($lineNum)
#for key in "${!ary[#]}";
# do
# sed -i '$ary[$key]'d /etc/mysql/my.cnf;
# #The folllowing line errors#
# sed -i "'$ary[$key]'imax_allowed_packet = 32M" /etc/mysql/my.cnf;
# #The above line errors#
#done
#for val in "${ary[#]}";
# do
# sed -i "${val}d" /etc/mysql/my.cnf;
# sed -i "${val}imax_allowed_packet = 32M" /etc/mysql/my.cnf;
# done
for val in "${ary[#]}";
do
sed -i "${val}s/.*/imax_allowed_packet = 32M" /etc/mysql/my.cnf";
done
For the first stanza of script I get the following output:
Error: sed: -e expression #1, char 1: unknown command: `''
For the second Stanza I get the following output:
sed: -e expression #1, char 3: unknown command:
'
sed: -e expression #1, char 3: unknown command:
'
For the third Stanza I get the following output:
./test.sh: line 22: unexpected EOF while looking for matching `"'
./test.sh: line 24: syntax error: unexpected end of file
Edit, rewriting the sed commands as sed -i "${ary[$key]}" generates the following error output: sed: -e expression #1, char 3: unknown command: `
I think you're over-complicating the issue. Your script can be reduced to this:
sed 's/\(max_allowed_packet\).*/\1 = 32M/' /etc/mysql.cnf
This performs a substitution on every occurrence of max_allowed_packet, setting the rest of the line to = 32M. Add the -i switch to overwrite the file when you're happy with the result.
Problems with your attempt
Shell parameters are not expanded within single quotes, so you would need to use double quotes, e.g. sed -i "${ary[$key]}d". You can use set -x to see what is happening here - at the moment, you will see the literal string $ary[$key], rather than the array value.
If I understand your intention correctly (you want to substitute the entire line), there's no need to call sed twice:
for val in "${ary[#]}"; do
sed -i.bak "${val}s/.*/imax_allowed_packet = 32M" /etc/mysql/my.cnf
done
I have chosen to loop through the values of the array, instead of the keys, in order to simplify things a little. When using the -i option, it is always a good idea to specify a backup file, as I have done.

sed with replacement part given as input from command line

I am trying to pass command line argument as the replacement part to sed command. But $1 doesn't work for me.
For example I unsuccesfully tried
function changeversion() {
sed -i 's/[0-9]\+/$1/g' file.xml;
}
which only replaced all numbers in file with '$1' text.
How can I fix it?
I think you need to put the expression in double qoutes to get variable substitution
function changeversion() {
sed -i "s/[0-9]\+/$1/g" file.xml;
}

Resources