I have a situation where I want to replace multiple line text in a file using sed.
The search text is:
Enable=Yes
UseTest=No
UseTempS=No
UseStatic=No
IPAddress=
SubnetMask=
DefaultGateway=
And the text to be replaced is
Enable=No
UseTest=No
UseTempS=No
UseStatic=No
IPAddress=0.0.0.0
SubnetMask=255.255.255.0
DefaultGateway=1.1.1.1
Any help will be appreciated.
Code for GNU sed:
sed -r 's#(.*)=(.*)#/\1=/s/=.*/=\2/#' file2|sed -f - file1
Session protocol:
$ cat file1
Enable=Yes
UseTest=No
UseTempS=No
UseStatic=No
IPAddress=
SubnetMask=
DefaultGateway=
$ cat file2
Enable=No
UseTest=No
UseTempS=No
UseStatic=No
IPAddress=0.0.0.0
SubnetMask=255.255.255.0
DefaultGateway=1.1.1.1
$ sed -r 's#(.*)=(.*)#/\1=/s/=.*/=\2/#' file2|sed -f - file1
Enable=No
UseTest=No
UseTempS=No
UseStatic=No
IPAddress=0.0.0.0
SubnetMask=255.255.255.0
DefaultGateway=1.1.1.1
If you want to match those fields in order, as you read them, one portable way:
sed -e '/Enable=Yes/!b;N;
/UseTest=No/!b;N;
/UseTempS=No/!b;N;
/UseStatic=No$/!b;N;
/IPAddress=$/!b;N;
/SubnetMask=$/!b;N;
/DefaultGateway=$/!b;
s/.*//;rtemplate' input
template
Enable=No
UseTest=No
UseTempS=No
UseStatic=No
IPAddress=0.0.0.0
SubnetMask=255.255.255.0
DefaultGateway=1.1.1.1
cat yourfile.txt | sed -f zarmacimamadzaghli.sed
zarmacimamadzaghli.sed
s/Enable=Yes/Enable=No/
s/UseTest=No/UseTest=No/
s/UseTempS=No/UseTempS=No/
s/UseStatic=No/UseStatic=No/
s/IPAddress=/IPAddress=0.0.0.0/
s/SubnetMask=/SubnetMask=255.255.255.0/
s/DefaultGateway=/DefaultGateway=1.1.1.1/
Related
I am trying to insert the contents of a file1.txt into file2.txt using sed. The content of file1.txt is just a single line, which is a path.
I want it to be added as a prefix to each line in file2.txt as well as add another / character.
$ cat file1.txt
/psot/rot8888/orce/db/tier/data/tine
$ cat file2.txt
o1_mf_users_abchwfg_.dbf
o1_mf_toptbs2_abchrq0_.dbf
o1_mf_toptbs1_abchrl2_.dbf
o1_mf_toptbs1_abchtlf_.dbf
Desired output should be like:
/psot/rot8888/orce/db/tier/data/tine/o1_mf_users_abchwfg_.dbf
/psot/rot8888/orce/db/tier/data/tine/o1_mf_toptbs2_abchrq0_.dbf
/psot/rot8888/orce/db/tier/data/tine/o1_mf_toptbs1_abchrl2_.dbf
/psot/rot8888/orce/db/tier/data/tine/o1_mf_toptbs1_abchtlf_.dbf
Tried command:
$ sed '/o1/ r file1.txt' file2.txt >> test.txt
$ cat test.txt
o1_mf_users_abchwfg_.dbf
/psot/rot8888/orce/db/tier/data/tine
o1_mf_toptbs2_abchrq0_.dbf
/psot/rot8888/orce/db/tier/data/tine
o1_mf_toptbs1_abchrl2_.dbf
/psot/rot8888/orce/db/tier/data/tine
o1_mf_toptbs1_abchtlf_.dbf
/psot/rot8888/orce/db/tier/data/tine
You can use pr for this without having to worry about sed metacharacters, delimiters, etc.
$ cat ip.txt
abcd.xyz
123.txt
foo_baz.txt
$ cat f1
/a/b/c/d/
$ pr -mts"$(< f1)" /dev/null ip.txt
/a/b/c/d/abcd.xyz
/a/b/c/d/123.txt
/a/b/c/d/foo_baz.txt
Where -m allows pasting files parallely and -s is the separator between the files to be merged. Here, /dev/null is used as a dummy for one of the files as only the separator has to be prefixed.
If you need to add some more characters after the contents of file containing the prefix:
$ cat ip.txt
abcd.xyz
123.txt
foo_baz.txt
$ cat f1
/a/b/c/d
$ pr -mts"$(< f1)"'/' /dev/null ip.txt
/a/b/c/d/abcd.xyz
/a/b/c/d/123.txt
/a/b/c/d/foo_baz.txt
This will work using any awk in any shell on every UNIX box:
$ awk 'NR==FNR{p=$0; next} {print p "/" $0}' file1 file2
/psot/rot8888/orce/db/tier/data/tine/o1_mf_users_abchwfg_.dbf
/psot/rot8888/orce/db/tier/data/tine/o1_mf_toptbs2_abchrq0_.dbf
/psot/rot8888/orce/db/tier/data/tine/o1_mf_toptbs1_abchrl2_.dbf
/psot/rot8888/orce/db/tier/data/tine/o1_mf_toptbs1_abchtlf_.dbf
This might work for you (GNU sed):
sed '1h;1d;G;s/\(.*\)\n\(.*\)/\2\1/' file1 file2
Copy file1 into the hold space and append it to each line in file2. Using regexp and back references, manipulate the two lines into one in the correct order.
Alternative:
sed 'x;s/.*/cat file1/e;G;s/\n//' file2
Insert file1 into the hold space, append the current line of file2, and remove the newline connecting them.
A third way:
sed 'r file1' file2 | sed -E 'N;s/(.*)\n(.*)/\2\/\1/'
I'm having the following string in a file called test.txt,
test.log test1.log test2.log
I want to replace it with
test.log -A test1.log -A test2.log
I tried:
sed -i 's/.log/.log -A/g' test.txt
But the output is
test.log -A test1.log -A test2.log -A
I don't want that to be appended in the last file. Can someone help me on this?
If the arguments are separated by space and final argument in the line doesn't have spaces after it, you could use this:
$ cat ip.txt
test.log test1.log test2.log
$ sed 's/\.log /&-A /g' ip.txt
test.log -A test1.log -A test2.log
since . is a metacharacter, you have to use \. to match it literally
& in replacement section represents entire matched portion in search section
You could also use awk here, better suited for field processing and added advantage of stripping away whitespaces at start/end of line
$ awk -v OFS=' -A ' '/\.log/{$1=$1} 1' ip.txt
test.log -A test1.log -A test2.log
default input field separator(FS) is one or more contiguous whitespace, so no need to set that
-v OFS=' -A ' set space followed by -A and space as output field separator(OFS)
/\.log/ if line contains .log
$1=$1 re-build input record, so that input FS will be replaced by OFS
1 idiomatic way to print input record
note that this solution won't change a line if it doesn't contain .log
I have a sed command which will append a string on the end of a line. When I re-run the same command again the same content is getting append at the end of the line again and again.
I am looking for a command which will check if the content is already there or not then proceed.
Here is my sed command:
shell: sed -i '/only_from/s/$/ xx.xx.xx.xx\/24/' file.txt
this line works for your needs:
sed -i '/only_from/{/ xx\.xx\.xx\.xx\/24$/!s#$# xx.xx.xx.xx/24#}' file
E.g:
kent$ cat f
only_from foo bar
kent$ sed -i '/only_from/{/xx\.xx\.xx\.xx\/24$/!s#$# xx.xx.xx.xx/24#}' f
kent$ cat f
only_from foo bar xx.xx.xx.xx/24
kent$ sed -i '/only_from/{/xx\.xx\.xx\.xx\/24$/!s#$# xx.xx.xx.xx/24#}' f
kent$ cat f
only_from foo bar xx.xx.xx.xx/24
You can try this sed:
sed '/only_from/{ / xx\.xx\.xx\.xx\/24/ !s/$/ xx\.xx\.xx\.xx\/24/}' file
This might be a bit naive, but why don't you write something as simple as
sed -i '/only_from$/s/$/ xx.xx.xx.xx\/24/' file.txt
file1 contains:
first=stan
last=smith
I want to create file2 which contains
first=homer
last=simpson
script.sh contains
#!/bin/bash
sed s/stan/$1/ file1 >tempfile
sed s/smith/$2/ tempfile >file2
rm tempfile
script.sh homer simpson does what I want.
Is there a better way to do this in a bash script without creating and deleting tempfile?
Yes you can:
$ s1="homer"
$ s2="simpson"
$ sed -e "s/stan/$s1/g" -e "s/smith/$s2/g" file1 > file2
$ cat file2
first=homer
last=simpson
As you can see the -e option is used to perform two different sed commands in the same line.
In a bash script:
#!/bin/bash
sed -e "s/stan/$1/g" -e "s/smith/$2/g" file1 > file2
Sed supports multiple expressions. So you can do something like:
sed -e "s/stan/$1/" -e "s/smith/$2/" file1 > file2
I also recommend to use double quotes to prevent wordsplitting.
Suppose I have a string like this
<start><a></a><a></a><a></a></start>
I want to replace values inside <start></start> like this
<start><ab></ab><ab></ab><ab></ab><more></more><vale></value></start>
How do I do this using Sed?
Try this :
sed 's#<start>.*</start>#<start><ab></ab><ab></ab><ab></ab></start>#' file
I get this line with gnu sed :
sed -r 's#(<start>)(.*)(</start>)#echo "\1"$(echo "\2"\|sed "s:a>:ab>:g")"\3"#ge'
see example:
kent$ echo "<start><a></a><a></a><a></a><foo></foo><bar></bar></start>"|sed -r 's#(<start>)(.*)(</start>)#echo "\1"$(echo "\2"\|sed "s:a>:ab>:g")"\3"#ge'
<start><ab></ab><ab></ab><ab></ab><foo></foo><bar></bar></start>
note
this will replace the tags between <start>s which ending with a . which worked for your example. but if you have <aaa></aaa>:
you could do: (I break it into lines for better reading)
sed -r 's#(<start>)(.*)(</start>)
#echo "\1"$(echo "\2"\|sed "s:<a>:<ab>:g;s:</a>:</ab>:g")"\3"
#ge'
e.g.
kent$ echo "<start><a></a><a></a><a></a><aaa></aaa><aba></aba></start>" \
|sed -r 's#(<start>)(.*)(</start>)#echo "\1"$(echo "\2"\|sed "s:<a>:<ab>:g;s:</a>:</ab>:g")"\3"#ge'
<start><ab></ab><ab></ab><ab></ab><aaa></aaa><aba></aba></start>
sed 's/(\<\/?)a\>/\1ab\>/g' yourfile, though that would get <a></a> that was outside <start> as well...
grep -rl 'abc' a.txt | xargs sed -i 's/abc/def/g'