sed is appending next line after replacing first line - linux

I want to replace USERNAME and PASSWORD in following properties files code using sed / awk
jdbc.connection.driver_class=com.ibm.as400.access.AS400JDBCDriver
jdbc.connection.username=USERNAME
jdbc.connection.password=PASSWORD
jdbc.minPoolSize=1
jdbc.maxPoolSize=15
I tried it using the following script
sed -i -e "s/^${JDBC_USER_KEY}=.*/${JDBC_USER_KEY}=${DATABASE_USER_NAME}/" \
-e "s/^${JDBC_PASSWORD_KEY}=.*/${JDBC_PASSWORD_KEY}=${DATABASE_PASSWORD}/" database.properties
Where :
JDBC_USER_KEY=jdbc.connection.username
DATABASE_USER_NAME=TEST
JDBC_PASSWORD_KEY=jdbc.connection.password
DATABASE_PASSWORD=TEST
But, the output is :
jdbc.connection.driver_class=com.ibm.as400.access.AS400JDBCDriver
jdbc.connection.username=TESTjdbc.connection.password=TEST
jdbc.minPoolSize=1
jdbc.maxPoolSize=15
The value has been replaced but the next line "jdbc.connection.password=TEST" has been appeneded with previous line.
I searched a lot on Google but did not find any solution/s.
I also tried awk (See the following):
awk 'BEGIN{ FS="=";OFS="=" } {if($1==pname) $2=newval; print $0,"\n"}' pname="$property_name" newval="$new_value" $ARTIFACTS_HOME/properties/$1 >> $ARTIFACTS_HOME/properties/test.properties
Where $property_name is jdbc.connection.username and $new_value is TEST.
Please help!

Related

remove character on the last line that specific word appears

we have the following file example
we want to remove the , character on the last line that topic word exists
more file
{"topic":"life_is_hard","partition":84,"replicas":[1006,1003]},
{"topic":"life_is_hard","partition":85,"replicas":[1001,1004]},
{"topic":"life_is_hard","partition":86,"replicas":[1002,1005]},
{"topic":"life_is_hard","partition":87,"replicas":[1003,1006]},
{"topic":"life_is_hard","partition":88,"replicas":[1004,1001]},
{"topic":"life_is_hard","partition":89,"replicas":[1005,1002]},
{"topic":"life_is_hard","partition":90,"replicas":[1006,1004]},
{"topic":"life_is_hard","partition":91,"replicas":[1001,1005]},
{"topic":"life_is_hard","partition":92,"replicas":[1002,1006]},
{"topic":"life_is_hard","partition":93,"replicas":[1003,1001]},
{"topic":"life_is_hard","partition":94,"replicas":[1004,1002]},
{"topic":"life_is_hard","partition":95,"replicas":[1005,1003]},
{"topic":"life_is_hard","partition":96,"replicas":[1006,1005]},
{"topic":"life_is_hard","partition":97,"replicas":[1001,1006]},
{"topic":"life_is_hard","partition":98,"replicas":[1002,1001]},
{"topic":"life_is_hard","partition":99,"replicas":[1003,1002]},
expected output
{"topic":"life_is_hard","partition":84,"replicas":[1006,1003]},
{"topic":"life_is_hard","partition":85,"replicas":[1001,1004]},
{"topic":"life_is_hard","partition":86,"replicas":[1002,1005]},
{"topic":"life_is_hard","partition":87,"replicas":[1003,1006]},
{"topic":"life_is_hard","partition":88,"replicas":[1004,1001]},
{"topic":"life_is_hard","partition":89,"replicas":[1005,1002]},
{"topic":"life_is_hard","partition":90,"replicas":[1006,1004]},
{"topic":"life_is_hard","partition":91,"replicas":[1001,1005]},
{"topic":"life_is_hard","partition":92,"replicas":[1002,1006]},
{"topic":"life_is_hard","partition":93,"replicas":[1003,1001]},
{"topic":"life_is_hard","partition":94,"replicas":[1004,1002]},
{"topic":"life_is_hard","partition":95,"replicas":[1005,1003]},
{"topic":"life_is_hard","partition":96,"replicas":[1006,1005]},
{"topic":"life_is_hard","partition":97,"replicas":[1001,1006]},
{"topic":"life_is_hard","partition":98,"replicas":[1002,1001]},
{"topic":"life_is_hard","partition":99,"replicas":[1003,1002]}
we try to removed the character , from the the last line that contain topic word as the following sed cli but this syntax not renewed the ,
sed -i '${s/,[[:blank:]]*$//}' file
sed (GNU sed) 4.2.2
In case you have control M characters in your Input_file then remove them by doing:
tr -d '\r' < Input_file > temp && mv temp Input_file
Could you please try following once. From your question what I understood is you want to remove comma from very last line which has string topic in it, if this is the case then I am coming up with tac + awk solution here.
tac Input_file |
awk '/topic/ && ++count==1{sub(/,$/,"")} 1' |
tac
Once you are happy with above results then append > temp && mv temp Input_file to above command too, to save output into Input_file itself.
Explanation:
Atac will read Input_file from bottom line to first line then passing it's output to awk where I am checking if first occurrence of topic is coming remove comma from last and rest of lines simply print then passing this output to tac again to make Input_file in original form again.
You should use the address $ (last line):
sed '$s/,$//' file
Using awk:
$ awk '{if(NR>1)print p;p=$0}END{sub(/,$/,"",p);print p}' file
Output:
...
{"topic":"life_is_hard","partition":98,"replicas":[1002,1001]},
{"topic":"life_is_hard","partition":99,"replicas":[1003,1002]}

How to find and replace the string with iterated values (multi lines) in shell script

this is my shell script to replace the string
OPTIONS="-p ${PIDFILE}"
with multi line string values
OPTIONS_1234="-p ${PIDFILE_1234} -ORBEndpoint iiop://localhost:1234"
OPTIONS_1235="-p ${PIDFILE_1235} -ORBEndpoint iiop://localhost:1235"
OPTIONS_1236="-p ${PIDFILE_1236} -ORBEndpoint iiop://localhost:1236"
based on my input port number , that many OPTIONS should be created.
#!/bin/bash
NS_HOSTNAME= localhost
namingService_ports = 1234,1235,1236
IFS=','
read -r -a portArray <<< "$namingService_ports"
for port in ${portArray[#]}; do
sed '0,/\PTIONS="-p ${PIDFILE}"/ s//\OPTIONS_'"$port"'="-p ${PIDFILE_'"$port"'} -ORBEndpoint iiop:\/\/'"$NS_HOSTNAME"':'"$port"'"\n /' "/etc/init.d/tao" > "tao_ns1"
done
can some suggest me how sed command will take the multi line with for loop and move to the file "tao_ns1"
You basically have 3 issues with your script.
The assignment namingService_ports = 1234,1235,1236 is incorrect in bash and it should be without spaces, i.e. namingService_ports="1234,1235,1236"
There is a typographical error in first sed option for OPTIONS i.e. sed '0,/\PTIONS="-p ${PIDFILE}" should have been sed '0,/\OPTIONS="-p ${PIDFILE}"
And while writing to a file "tao_ns1" you are using the > operator which basically over-writes the file every-time you run it. It should have been the >> append operator, which appends the new line to the file for every iteration of the loop.
Also http://www.shellcheck.net/, that you have carriage return characters in your script, run tr command on it before proceeding next.
tr -d '\r' < current_script.sh > new_script.sh
With the above fixes made.
#!/bin/bash
NS_HOSTNAME="localhost"
namingService_ports="1234,1235,1236"
IFS=','
read -r -a portArray <<< "$namingService_ports"
for port in ${portArray[#]}; do
sed '0,/\OPTIONS="-p ${PIDFILE}"/ s//\OPTIONS_'"$port"'="-p ${PIDFILE_'"$port"'} -ORBEndpoint iiop:\/\/'"$NS_HOSTNAME"':'"$port"'"\n /' "/etc/init.d/tao" >> "tao_ns1"
done
should work fine.
Two examples that I hope helps to reach want you want to ...
Changing a string and redirect the result to a new file, replacing AAA to BBB:
echo "xxxAAAxxx" | sed "s/AAA/BBB/i" > out.ini
Same logic (replacing BBBto CCC), but at this time replace some string inside an existing file
sed -i "s/BBB/CCC/i" out.ini

How to find a match in file and then suffix that match

I have a file "test.xml"
That looks like the below:
CLASS="BAKERS"
GROUP="ABCYYYYY"
TRACK="DASD"
OWNERS="ALPHA"
GROUP="ABCXXXXX"
GROUP="ABCZZZZZ"
I want to use a single SED line command to find all occurrences of GROUP="ABC
Then within the "" I want add suffix: _DONE to all the matches found.
So the result should look like:
CLASS="BAKERS"
GROUP="ABCYYYYY_DONE"
TRACK="DASD"
OWNERS="ALPHA"
GROUP="ABCXXXXX_DONE"
GROUP="ABCZZZZZ_DONE"
This is the command I am using:
`sed -i.bkp '/^GROUP="ABC/ s/$/_DONE"/' test.xml`
but it is appending after the " and not within the ""
It's almost that. But $ means end of line so you have to substitute the last " using "$ instead:
sed -i.bkp '/^GROUP="ABC/ s/"$/_DONE"/' test.xml
you could also specify that there is some blank after the " with for instance "[ \t]*$
this may help:
sed -i 's/^GROUP="ABC[^"]*/&_DONE/' file
Try doing this but without the backticks :
sed -i.bak '/^GROUP="ABC/s/"$/_DONE"/' file
You can use this sed command
sed '/GROUP="ABC/s/\(.*\)"/\1_DONE"/'
Output :
CLASS="BAKERS"
GROUP="ABCYYYYY_DONE"
TRACK="DASD"
OWNERS="ALPHA"
GROUP="ABCXXXXX_DONE"
GROUP="ABCZZZZZ_DONE"
Use this:
sed -i.bkp 's/GROUP="ABC[A-Z]*/&_DONE/g' test.xml
I tested with your example and worked.

how to edit a line using sed or awk in linux containing a certain number or string

My Stress.k file is as follows
180.4430
*INCLUDE
$# filename
*STRESS_INITIALIZATION
*END
I want it to be like
180.4430
*INCLUDE
$# filename
*STRESS_INITIALIZATION
*/home/hassan/534.k
*END
for that I used sed as follows
a="$(cat flow.k)"
sed -i -e '/*END/i \*/home/hassan/$a.k ' Stress.k
where flow.k has only a single number like 534.k or something . Here sed put the line before END but it doesn't take the value of a , instead it puts the same alphabet and it doesn't understand $a.k.
Please also tell me how to delete the second last line or the line with a string hassan for example so that I can delete it first and the for the next step I use it to enter my required line.
if possible please also suggest the alternatives.
best regards
bash variables are only replaced when in double quotes, e.g.
sed -i -e "/*END/i \*/home/hassan/$a.k " Stress.k
Use double quotes to allow the variable to be expanded.
sed -i -e "/*END/i \*/home/hassan/$a.k " Stress.k
To replace the string, do it as you read in the file:
a=$(sed 's/534/100/' flow.k)
To delete a line:
sed '/hassan/d' inputfile
To read a file into the stream after the current line:
sed '/foo/r filename' inputfile

how to replace specific record on a line containg a string with a number from another file using inplace editing sed in linux

I have an input file like following.
R sfst 1000.0000
$ new time step for mass scaled calculation
R dt2ms -4.000E-7
$ friction value for blank
R mue 0.120000
$ blankholder force
R bhf 2.0000E+5
$ simulation time
R endtime 0.150000
i want to change the value on the line containing 'mue'
with following I can read it but cant change it.
awk ' /mue/ { print $3 } ' input.txt
The value is to be taken from another file fric.txt.
fric.txt contains only numbers, one on each line .
fric.txt has data like
0.1234
0.234
0.0234
.
.
Blockquote
It should be noted that ONLY the FIRST instance need to be replaced and the format i.e. white spacing be kept cosntant.
Blockquote
Can anybody guide me doing this using sed or awk?
Try this command:
$ awk '/mue/ && !seen {getline $3 <"fric.txt"; seen=1} 1' input.txt
This might work for you:
sed '/\<mue\>/!d;=;s/.* \([^ ]\+\).*/\1/;R fric.txt' input.txt |
sed 'N;N;s|\n|s/|;s|\n|/|;s|$|/|;q' >temp.sed
sed -i -f temp.sed input.txt
You can do it with a sed in the sed (assuming you like to take line 1 from fric.txt):
sed -ir 's/(.*mue[ \t]+)[0-9.]+(.*)/\1'$(sed -n '1{p;q}' fric.txt)'\2/' input.txt

Resources