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

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.

Related

sed replace string with space and special characters

The test23 file contains a line
root_url = %(protocol)s://%(domain)s:%(http_port)s/
I need to replace this with
root_url = %(protocol)s://%(domain)s:%(http_port)s/grafana
This below steps in the script doesn't work.
line_old='root_url = %(protocol)s://%(domain)s:%(http_port)s/'
line_new='root_url = %(protocol)s://%(domain)s:%(http_port)s/grafana'
sed -i "s/\${line_old}\/\${line_new}/\g" test23
Try changing delimiter of sed:
sed -i "s|${line_old}|${line_new}|g" test23
example
echo "${line_old}" | sed "s|${line_old}|${line_new}|g"
root_url = %(protocol)s://%(domain)s:%(http_port)s/grafana
I would use:
sed '/^root_url[ ][=]/s/$/grafana/' filename
Where:
/^root_url[ ][=]/ locates the line beginning with "root_url =", then
the normal substitution form 's/$/grafana/' simply appends "grafana" to the end of the line.
(note: add -i to edit the file in-place, or add -i.bak to edit in-place preserving a copy of the original file unchanged in filename.bak)
Results
root_url = %(protocol)s://%(domain)s:%(http_port)s/grafana
Look things over and let me know if that meets your needs and if you have any questions.

How to replace a string (characters and numbers)

I would like to replace rs101 to rs102, however it shows unterminated "s" command with this.
sed -i 's/rs101/rs102' file.name.
Is there any other solution ?
You should insert / after rs102 .
sed -i 's/rs101/rs102/' file.name.
Syntax for Search and Replace:
sed 's/search/replace/' file.name

sed is appending next line after replacing first line

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!

SED: How to insert string to the beginning of the last line

How to insert string to the beginning of the last line?
I want to add a time stamp to a text file which contains multiple lines
var1 = `date`
LINE1
LINE2
LINE3
...
(INSERT var1 here) LASTLINE
sed 's/^/test line /g' textfile inserts characters to the beginning of every line but how can I specifically modify the last line only?
Thanks
Going forward:
sed '$s/^/sample text /' textfile works, but only when inserting regular strings. If I try
var1 = "sample text"
and use substition, here are the problems I encounter
using single quotes in sed does not expand variables, so sed '$s/^/$var1/' textfile will insert the string $var1 into the beginning of the last line.
To enable variable substitution I tried using double quotes. It works when I specify the exact line number. something like:
sed "5s/^/$var1/" textfile
But when I try sed "$s/^/$var1" text file, it returns an error:
sed: -e expression #1, char 5: extra characters after command
Can someone help me please?
Like this:
sed '$s/^/test line /' textfile
$ indicates last line. Similarly, you can insert into a any specific line by putting the line number in place of $
But when I try sed "$s/^/$var1" text file, it returns an error:
It returns an error because the shell attempts to expand $s since you've used double quotes. You need to escape the $ in $s.
sed "\$s/^/$var1/" filename
sedshould be the best tool, but awk can do this too:
awk '{a[++t]=$0} END {for (i=1;i<t;i++) print a[i];print v$0}' v="$var1" file
It will insert value of var1 in front of last line
Another variation
awk 'NR==f {$0=v$0}1' v="$var1" f=$(wc -l file)
PS you do not need to specify file after awk, not sure why. If you do so, it reads it double.
This command would work for you:
sed -i "5s/^/$var1 /" text file

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

Resources