sed with replacement part given as input from command line - bash

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;
}

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

Search Replace Sed using wild card

Hello I'm sort of new to scripting and have the following problem
I need to replace 20069.1216.0
HintPath..\packages\String.20069.1216.0\lib\net\Thoo.Tkc.dll/HintPath
This works fine at replacing 20069.1216.0 with whatever is provided in $2
`xargs sed -i 's/String.20.........0/String.'"${2}"'/g'`
I need a way for sed to search for **"String.*\lib\net\"**where anything in between **String.** and **\lib...** is wildcard
This what i have tried
sed -i 's/String.*\/String.'"${2}"'/g'
sed -i 's/String.*\\/String.'"${2}"'/g'
sed -i 's/String.\(.*\)\\/String.'"${2}"'/g'
I'll assume that you call sed inside a function.
So try this code:
#!/bin/bash
replace() {
echo 'HintPath..\packages\String.20069.1216.0\lib\net\Thoo.Tkc.dll/HintPath' |\
sed "s/String\.[0-9.]*/String\.${2}/"
}
replace dont_care filename
If your path may contain --SNAPSHOT this solution should work for you:
#!/bin/bash
replace() {
echo 'HintPath..\packages\String.20069.1216.0--SNAPSHOT\lib\net\Thoo.Tkc.dll/HintPath' |\
sed "s/String[0-9.]*\(--SNAPSHOT\)\{0,1\}/String\.${2}/"
}
replace dont_care filename

Sed insert blank line below search string then insert string on the next line

I have a sed expression in a function that I pass parameters to.
insert_after_new_line() {
if ! grep -q "${2}" "${3}"; then
sed -i "/${1}/{N;N;a ${2}}" "${3}"
fi
}
insert_after_new_line search insert textfile.txt
I am trying to have a blank line inserted below the search string and the insert string inserted after.
so
text
text
search
text
becomes
text
text
search
insert
text
but I keep getting the error
sed: -e expression #1, char 0: unmatched `{'
I tested this. works in command line
sed -i '/search/a \\ninsert' file
sed really delimiters commands by a newline. There is a ; but it does not work for all commands, mostly these which take file name as an argument. ; does not work for r R or for example a. Sed will read everything after a command, so sed interprets is like a ${2}} as a single command, in result it does not find enclosing }, cause it's been eaten by a command. You need a newline:
sed -i "/${1}/{N;N;a ${2}
}" "${3}"
or
sed -i "/${1}/{N;N;a ${2}"$'\n'"}" "${3}"
this should work:
sed -i '/search/{G;ainsert
}' file
You can replace the text by shell variable, but replace the single quotes by double quotes too.

Replace an unknown string within a line using Bash

I want to be able to modify db001 with a string I pass into the command via CLI. At any given time db001 could be a different value so I can't just look for that value.
./myscript modify_db <new value>
myfile.txt
./myscript modify_db mynewdbname002
Before: database_node=db001.mydomain.local
After: database_node=mynewdbname002.mydomain.local
./myscript modify_db db003
Before: database_node=mynewdbname002.mydomain.local
After: database_node=db003.mydomain.local
You can use this sed command inside your script:
sed "s/^\(database_node=\)[^.]*/\1$1/" file
Example:
s='database_node=db001.mydomain.local'
repl() {
sed "s/^\(database_node=\)[^.]*/\1$1/" <<< "$s";
}
and call it as:
repl mynewdbname002
database_node=mynewdbname002.mydomain.local
repl db003
database_node=db003.mydomain.local
You could have a script like, just like below taking an input argument having the replacement value,
#!/bin/bash
perl -lpe "s/database_node=(\w+)/database_node=$1/g" file
and just do
./script.sh newdbname
Use the -i flag for in-place replacement and -i.bak for in-place replacement with a backup of your original file
perl -lpe -i.bak "s/database_node=(\w+)/database_node=$1/g" file
(or) with a simple bash function
function replaceFile() {
perl -lpe -i.bak "s/database_node=(\w+)/database_node=$1/g" file
}
I would avoid trying to produce the new state from the previous state and rather just use a template :
function modify_db() {
echo "database_node=$1.mydomain.local"
}
I use echo here for illustration but you should obviously do whatever you want to do with the "database_node=$1.mydomain.local".
Supposing it should modify the only line starting with database_node from a file db_conf after having printed the old value :
function modify_db() {
echo "Before: $(grep '^database_node=' db_conf)"
sed -i "s/^database_node=.*\.mydomain\.local/database_node=$1.mydomain.local/" db_conf
echo "After: $(grep '^database_node=' db_conf)"
}

Add a line after an occurrence

The variables are
espejo=u456789
usuario=u123456
grupo=unixgr
I want to add after the line occurrence of variable $espejo, the text in variables $usuario and $grupo:
cp $DIRECTORY/usu.txt $DIRECTORY/usu.txt.`date '+%F'`
sed "/${espejo}/a\ ${usuario} ${grupo}" $DIRECTORY/usu.txt.`date '+%F'` > $DIRECTORY/usu.txt
I got this error during the execution:
sed: 0602-404 Function /u456789/a\u123456 unixgr cannot be parsed.
I don't know what is wrong.
Try the following:
sed "/${espejo}/a\
${usuario} ${grupo}" $DIRECTORIO/usu.txt.`date '+%F'` > $DIRECTORIO/usu.txt
Note that after the backslash on first line there is no any other symbols except new line.
Try this:
sed "s:${espejo}:${espejo}\n${usuario} ${grupo}:" $DIRECTORIO/usu.txt.`date '+%F'` > $DIRECTORIO/usu.txt
If the above just adds n instead of newline, try this:
sed "s:${espejo}:${espejo}\
${usuario} ${grupo}:" $DIRECTORIO/usu.txt.`date '+%F'` > $DIRECTORIO/usu.txt
This will append the new variable in new line. I guess you are facing the problem since ${espejo} contains / character in it.
This might work for you (GNU sed):
sed "/$espejo/r /dev/stdin" file <<<" ${usuario} ${grupo}"

Resources