Using bash how do I find a string and update the string next to it for example pass value
my.site.com|test2.spin:80
proxy_pass.map
my.site2.com test2.spin:80
my.site.com test.spin:8080;
Expected output is to update proxy_pass.map with
my.site2.com test2.spin:80
my.site.com test2.spin:80;
I tried using awk
awk '{gsub(/^my\.site\.com\s [A-Za-z0-9] \.spin:8080;$/,"my.site2.comtest2.spin:80"); print}' proxy_pass.map
but does not seem to work. Is there a better way to approch the problem. ?
CodePudding user response:
With your shown samples and attempts please try following awk
code. Creating shell variable named var
where it stores value my.site.com|test2.spin:80
in it. which further is being passed to awk
program. In awk
program creating variable named var1
which has shell variable var's value in it.
In BEGIN
section of awk
using split
function to split value of var
(shell variable's value container) into array named arr with separator as |
. Where num
is total number of values delimited by split function. Then using for
loop to be running till value of num
where it creates array named arr2
with index of current i
value and making i 1 as its value(basically 1 is for key of array and next item is value of array).
In main block of awk
program checking condition if $1
is in arr2 then print arr2's value else print $2 value as per requirement.
##Shell variable named var is being created here...
var="my.site.com|test2.spin:80"
awk -v var1="$var" '
BEGIN{
num=split(var1,arr,"|")
for(i=1;i<=num;i =2){
arr2[arr[i]]=arr[i 1]
}
}
{
print $1,(($1 in arr2)?arr2[$1]:$2)
}
' Input_file
OR in case you want to maintain spaces between 1st and 2nd field(s) then try following code little tweak of Above code. Written and tested with your shown samples Only.
awk -v var1="$var" '
BEGIN{
num=split(var1,arr,"|")
for(i=1;i<=num;i =2){
arr2[arr[i]]=arr[i 1]
}
}
{
match($0,/[[:space:]] /)
print $1 substr($0,RSTART,RLENGTH) (($1 in arr2)?arr2[$1]:$2)
}
' Input_file
NOTE: This program can take multiple values separated by |
in shell variable to be passed and checked on in awk
program. But it considers that it will be in format of key|value|key|value...
only.
CodePudding user response:
If the number of spaces between the columns is not significant, a simple
proxyf=proxy_pass.map
tmpf=$$.txt
awk '$1 == "my.site.com" { $2 = "test2.spin:80;" } {print}' <$proxyf >$tmpf && mv $tmpf $proxyf
should do. If you need the columns to be lined up nicely, you can replace the print
by a suitable printf ....
statement.
CodePudding user response:
One awk
idea, assuming spacing needs to be maintained:
awk -v rep='my.site.com|test2.spin:80' '
BEGIN { split(rep,a,"|") # split "rep" variable and store in
site[a[1]]=a[2] # associative array
}
$1 in site { line=$0 # if 1st field is in site[] array then make copy of current line
match(line,$1) # find where 1st field starts (in case 1st field does not start in column #1)
newline=substr(line,1,RSTART RLENGTH-1) # save current line up through matching 1st field
line=substr(line,RSTART RLENGTH) # strip off 1st field
match(line,/[^[:space:];] /) # look for string that does not contain spaces or ";" and perform replacement, making sure to save everything after the match (";" in this case)
newline=newline substr(line,1,RSTART-1) site[$1] substr(line,RSTART RLENGTH)
$0=newline # replace current line with newline
}
1 # print current line
' proxy_pass.map
This generates:
my.site2.com test2.spin:80
my.site.com test2.spin:80;
If the input looks like:
$ cat proxy_pass.map
my.site2.com test2.spin:80
my.site.com test.spin:8080;
This awk
script generates:
my.site2.com test2.spin:80
my.site.com test2.spin:80;
NOTES:
- if multiple replacements need to be performed I'd suggest placing them in a file and having
awk
process said file first - the 2nd
match()
is hardcoded based on OP's example; depending on actual file contents it may be necessary to expand on the regex used in the 2ndmatch()
CodePudding user response:
#!/bin/sh -x
f1=$(echo "my.site.com|test2.spin:80" | cut -d'|' -f1)
f2=$(echo "my.site.com|test2.spin:80" | cut -d'|' -f2)
echo "${f1}%${f2};" >> proxy_pass.map
tr '%' '\t' < proxy_pass.map >> p1
cat > ed1 <<EOF
$
-1
d
wq
EOF
ed -s p1 < ed1
mv -v p1 proxy_pass.map
rm -v ed1