How to escape single quotes in Jenkins pipeline sed command? - bash

I cant seem to figure out how to get to write this in Jenkins pipeline?
sed -i "txt" "s/id 'com.github' ver '1.0'/id 'com.github'/g" file.txt
This is what i have been trying so far
sh """sed -i "txt" "s/id \'com.github\' ver \'1.0\'/id \'com.github\'/g" file.txt"""
I have a file with content -
id 'com.github' ver '1.0'
I want to remove
ver '1.0'
from
id 'com.github' ver '1.0'
using a bash command. How can I do this?

I would use ed instead.
printf '%s\n' "s/\(id 'com.github'\) ver '1.0'/\\1/" wq | ed file.txt
Note that the quoting issue can be fixed in sed (you are unnecessarily escaping the single quotes), but ed is more standard and designed for what you are trying to do: edit a file in place.

This worked for me in Jenkinsfile -
script {
dir('mydir') {
def command = $/sed -i "s/id 'com.github' ver '1.0'/id 'com.github'/" ./file.txt/$
SED_OUT = sh(returnStdout: true, script: command)
}
}

Related

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

Trying to swap JSON element using sed editor on MAC

I am trying to create a script to find a JSON element and update it with the arg values.
#!/bin/bash
# Shell script to verify the end to end D1 request flow
placeLocation=$1
vehicleHeading=$2
message=$3
file=one.txt
sed -i '' '/location/c\ \"location\" : \"$placeLocation\",' $file
sed -i '' '/heading/c\ \"heading\" : \"$vehicleHeading\",' $file
sed -i '' '/message/c\ \"message\" : \"$message\",' $file
One.txt
"location":"<48.777098,9.181301> - 150.0m",
"message":"Hello there!",
"heading": "34",
But getting following error
sed: 1: "/location/c\ \"locati ...": extra characters after \ at the end of c command
sed: 1: "/heading/c\ \"heading ...": extra characters after \ at the end of c command
sed: 1: "/message/c\ \"message ...": extra characters after \ at the end of c command
sed: 1: "file.txt": invalid command code f
sed: 1: "file.txt": invalid command code f
sed: 1: "file.txt": invalid command code f
sed: 1: "file.txt": invalid command code f
I have just started learning about sed editor and tried out multiple things but couldn't able to figure it out. Any help is much appreciated!
Note that you probably should consider using a tool like jq for editing JSON files. But I assume you have a good reason for using sed, so you have a couple of problems there.
The first is that you're trying to use GNU sed features on your Mac OS X version of sed that doesn't have those features. If you want GNU sed on Mac OS X, then install it:
▶ brew install gnu-sed
Fixing up your code for GNU sed (and also for other Bash style guide recommendations about quoting strings):
cat > FILE <<EOF
"location":"<48.777098,9.181301> - 150.0m",
"message":"Hello there!",
"heading": "34",
EOF
placeLocation=myPlaceLocation
vehicleHeading=myVehicleHeading
message=myMessage
file=FILE
gsed -i -e '/location/c\' -e '"location": "'"$placeLocation"'",' "$file"
gsed -i -e '/heading/c\' -e '"heading": "'"$vehicleHeading"'",' "$file"
gsed -i -e '/message/c\' -e '"message": "'"$message"'",' "$file"
As noted in the GNU sed manual, use of multiple -e commands on the same line with the c\ command is a GNU extension.
If you want to use Mac OS X's sed, just may be able to write it this way:
sed -i '' '
s/"location".*/"location": "'"$placeLocation"'",/
s/"heading".*/"heading": "'"$vehicleHeading"'",/
s/"message".*/"message": "'"$message"'",/
' "$file"
But note you would have to sanitise the input if you need the code to be robust to all inputs.
To do this robustly you need to use a tool that understands literal strings (which sed doesn't - see Is it possible to escape regex metacharacters reliably with sed) e.g. awk:
$ awk 'BEGIN{FS=OFS=":"; val=ARGV[1]; ARGV[1]=""} $1=="\"message\""{sub(FS".*",FS); print $1, "\""val"\""}' 'what is 1/2?' one.txt
"message":"what is 1/2?"
$ awk 'BEGIN{FS=OFS=":"; val=ARGV[1]; ARGV[1]=""} $1=="\"message\""{sub(FS".*",FS); print $1, "\""val"\""}' 'what is 1&2?' one.txt
"message":"what is 1&2?"
$ awk 'BEGIN{FS=OFS=":"; val=ARGV[1]; ARGV[1]=""} $1=="\"message\""{sub(FS".*",FS); print $1, "\""val"\""}' 'what is \1?' one.txt
"message":"what is \1?"
the above will work robustly using any awk in any shell on every UNIX box. Try using those as replacement strings in a sed command.
The full script to do what you want would be:
#!/bin/env bash
# Shell script to verify the end to end D1 request flow
placeLocation=$1
vehicleHeading=$2
message=$3
file=one.txt
tmp=$(mktemp)
awk '
BEGIN {
split("location heading message", tags)
for (i in tags) {
vals["\"" tags[i] "\""] = "\"" ARGV[i] "\""
ARGV[i] = ""
}
FS=OFS=":"
}
$1 in vals {
tag = $1
sub(FS".*","")
$0 = tag OFS vals[tag]
}
1' "$placeLocation" "$vehicleHeading" "$message" "$file" > "$tmp" && mv "$tmp" "$file"

How do I replace text using a variable in a shell script

I have a variable with a bunch of data.
text = "ABCDEFGHIJK"
file = garbage.txt //iiuhdsfiuhdsihf]sdiuhdfoidsoijsf
What I would like to do is replace the ] charachter in file with text. I've tried using sed but I keep getting odd errors.
output should be:
//iiuhdsfiuhdsihfABCDEFGHIJKsdiuhdfoidsoijsf
Just need to escape the ] character with a \ in regex:
text="ABCDEFGHIJK"
sed "s/\(.*\)\]\(.*\)/\1$text\2/" file > file.changed
or, for in-place editing:
sed -i "s/\(.*\)\]\(.*\)/\1$text\2/" file
Test:
sed "s/\(.*\)\]\(.*\)/\1$text\2/" <<< "iiuhdsfiuhdsihf]sdiuhdfoidsoijsf"
# output => iiuhdsfiuhdsihfABCDEFGHIJKsdiuhdfoidsoijsf
There is always the bash way that should work in your osx:
filevar=$(cat file)
echo "${filevar/]/$text}" #to replace first occurence
OR
echo "${filevar//]/$text}" #to replace all occurences
In my bash i don't even have to escape ].
By the way, the simple sed does not work?
$ a="AA"
$ echo "garbage.txt //iiuhdsfiuhdsihf]sdiuhdfoidsoijsf" |sed "s/]/$a/g"
garbage.txt //iiuhdsfiuhdsihfAAsdiuhdfoidsoijsf

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)"
}

sed replace a single line

I am trying use sed to replace a single line.
Example:
space_left_action = EMAIL
admin_space_left_action = SUSPEND
I tried this command:
sed -i '/space_left_action*/c\space_left_action = SYSLOG' /etc/audit/auditd.conf
The result:
space_left_action = SYSLOG
space_left_action = SYSLOG
I do not want to replace the admin_space_left_action line, but still have the flexibility that if someone changes space_left_action value with something different sed will still replace the line.
use '^' for checking begining of line
sed -i '/^space_left_action*/c\space_left_action = SYSLOG' /etc/audit/auditd.conf
you also can try this
sed -i '/[^_]space_left_action*/c\space_left_action = SYSLOG' /etc/audit/auditd.conf
An awk version
awk '/^space_left_action/ {$3="SYSLOG"}1' /etc/audit/auditd.conf
space_left_action = SYSLOG
admin_space_left_action = SUSPEND

Resources