delete and replace a line using linux command - linux

I am trying to delete a line with the pattern matches and replacing the entire line with the another line using sed command.
File contents:Sample.txt
Testfile=xxxx
Testfile3=uuuu
Testfile4=oooo
Testfile5=iiii
Testfile2=ikeii
I am using sed command to delete a line contains Testfile3=* and replace by Testfile3=linechanged
sed -i 's/Testfile3=\*/Testfile3=linechanged/' Sample.txt.
But it just appends the replaceable string in the line as shown below
Testfile3=linechanged=uuuu.
I am expecting the output to be
Testfile3=linechanged.
What i am doing wrong?

The star is not matched right:
sed -i 's/Testfile3=.*/Testfile3=linechanged/' Sample.txt
# ^^
.* matches any character (.) for any length (*), so it will match everything till the end of the line.

You can use captured group to keep what will be preserved and use the desired replacement for the rest:
sed -i 's/^\(Testfile3=\).*/\1linechanged/' file.txt
In your case, escaping the Regex token * like \* will match * literally e.g. Testfile3=* would be matched then.

This might work for you (GNU sed):
sed '/Testfile3/cTestfile3=linechanged' file
This matches the line containing Testfile3 and changes it to the required string.

Related

sed command to delete starting pattern match with special character in it

I have sed command that delete line when string match with starting pattern
sed -i "/^Data\=C\b/Id" tally.ini
This work correctly for patch Data=C
But I want to match path Data=C:\ and that I want to delete this line.
How can this possible?
sed -i '/^Data\=C:\\/Id' tally.ini
Put the command in a single quoted string instead of double.
Escape the backslash.

Replace first sign in line (linux bash)

I want to delete first sign in a file (without creating new file). That is the line (and this line isn't the first one or last one):
#$config['rrdcached'] = "unix:/var/run/rrdcached.sock";
I'm trying to do thuis with sed command but it doesn't work. That is my command:
sed -i "s/#$config\['rrdcached'\].*$/$config\['config'\]/g" text.txt
Any suggestions?
Just replace the first match of # with following command:
sed -i '1 s/#//' test.txt
The $ characters are causing two problems.
First, the shell is treating $config as a variable reference, and replacing it with the value. You need to escape the $ to prevent that.
Second, $ has special meaning in regular expressions, so you need to escape it at that level as well. So you need to escape the backslash and the $.
sed -i "s/^#\\\$config\['rrdcached'\].*\$/\$config['config']/" text.txt
There's no need for the g modifier since you only want to replace the first match on the line. And you should use the ^ anchor so it only matches this at the beginning of the line.
It's also not necessary to escape special regexp characters in the replacement string.
This command works, but i forgot that there is something after '='. At now, everything after that is deleted.
I wrote this:
sed -i "s/^#\\\$config\['rrdcached'\] = "unix:/var/run/rrdcached.sock";.*\$/\\\$config\['config'\]/ = "unix:/var/run/rrdcached.sock";" text.txt

Filter out only matched values from a text file in each line

I have a file "test.txt" with the lines below and also lot bunch of extra stuff after the "version"
soainfra_metrics{metric_group="sca_composite",partition="test",is_active="true",state="on",is_default="true",composite="test123"} map:stats version:1.0
soainfra_metrics{metric_group="sca_composite",partition="gello",is_active="true",state="on",is_default="true",composite="test234"} map:stats version:1.8
soainfra_metrics{metric_group="sca_composite",partition="bolo",is_active="true",state="on",is_default="true",composite="3415"} map:stats version:3.1
soainfra_metrics{metric_group="sca_composite",partition="solo",is_active="true",state="on",is_default="true",composite="hji"} map:stats version:1.1
I tried:
egrep -r 'partition|is_active|state|is_default|composite' test.txt
It's displaying every line, but I need only specific mentioned fields like this below,ignoring rest of the data/stuff or lines
in a nut shell, i want to display only these fields from a line not the rest
partition="test",is_active="true",state="on",is_default="true",composite="test123"
partition="gello",is_active="true",state="on",is_default="true",composite="test234"
partition="bolo",is_active="true",state="on",is_default="true",composite="3415"
partition="solo",is_active="true",state="on",is_default="true",composite="hji"
If your version of grep supports Perl-style regular expressions, then I'd use this:
grep -oP '.*?,\K[^}]+' file
It removes everything up to the first comma (\K kills any previous output) and prints everything up to the }.
Alternatively, using awk:
awk -F'}' '{ sub(/[^,]+,/, ""); print $1 }' file
This sets the field separator to } so the part you're interested in is the first field. It then uses sub to remove the part up to the first comma.
For completeness, you could also use sed:
sed 's/[^,]*,\([^}]*\).*/\1/' file
This captures the part after the first , up to the } and replaces the content of the line with it.
After the grep to pick out the lines you want, use sed to edit the lines:
sed 's/.*\(partition[^}]*\)} map.*/\1/'
This means: "whenever you see anything .*, followed by partition and
any number of non-}, then } map and anything else, grab the part
from partition up to but not including the brace \(...\) as group 1.
The replacement text is just group 1 \1.
Use a pipe | to connect the output of egrep to the input of sed:
egrep ... | sed ...
As far as i understood your file might have more lines you don't want to see, so i would use:
sed -n 's/.*\(partition.*\)}.*/\1/p' file
we use -n p to show only lines where we made substitution. The substitution part just gets the part of the line you need substituting the whole line with the pattern.
This might work for you (GNU sed):
sed -r 's/(partition|is_active|state|is_default|composite)="[^"]*"/\n&\n/g;s/[^\n]*\n([^\n]*)\n[^\n]*/\1,/g;s/,$//' file
Treat the problem as if it were a "decomposed club sandwich". Identify the fillings, remove the bread and tidy up.

Inserting string in file in nth line after pattern using sed

I want to insert word after nth line after pattern using sed.
I tied to modify this command but it inserts only in first line after pattern.
sed -i '/myPattern/a \ LineIWantToinser ' myFile
What command should I use to insert for example in third line after pattern?
Easiest way to do it with GNU sed is.. (maybe some direct solution exists!?)
sed -n '/pattern/=' file
to see line where pattern is (grep also can be used here with -n)
then if linenumber+ numoflines is for example 123
sed '123aSOME INSERTED TEXT AFTER THAT LINE' file
where little a is append command (after that line, if i is used will be pre pattern line)
ps. I'm eager to see if #neronlevelu (or other sed Lover) will find some better sed solution.
Edit: i've found it, it seems a for append or i for insert must? be on first position on line when using { with ; inside } like
sed '/pattern/{N;N;N;
a SOME TEXT FOR INSERTING
}' file
sed '/pattern/{N;N;N;i \
Line to add after 3 lines with patterne as starting counter
' YourFile
number of N to add line between pattern and inserted line.
there is no check for end of file or pattern in the 3 lines. (not specified in PO)
A version with bash and ed:
ed -s myFile <<<$'/myPattern/+3a\n LineIWantToinser \n.\nwq'
ed enables us to use the line addressing /myPattern/+3.

sed replace string in a first line

How can I replace a string but only in the first line of the file using the program "sed"?
The commands s/test/blah/1 and 1s/test/blah/ don't seem to work. Is there another way?
This might work for you (GNU sed):
sed -i '1!b;s/test/blah/' file
will only substitute the first test for blah on the first line only.
Or if you just want to change the first line:
sed -i '1c\replacement' file
This will do it:
sed -i '1s/^.*$/Newline/' textfile.txt
Failing that just make sure the match is unique to line one only:
sed -i 's/this is line one and its unique/Changed line one to this string/' filename.txt
The -i option writes the change to the file instead of just displaying the output to stdout.
EDIT:
To replace the whole line by matching the common string would be:
sed -i 's/^.*COMMONSTRING$/Newline/'
Where ^ matches the start of the line, $ matches the end of the line and .* matches everything upto COMMONSTRING
this replaces all matches, not just the first match, only in the first line of course:
sed -i '1s/test/blah/g' file
the /g did the trick to replace more than one matches, if any exists.

Resources