Sed replace specific substring - sed

I have a file that's generated as an output to an SQL query. I need to replace the nulls in the file with blanks, so something like
sed -e"s/null//g" would work.
However there's a valid string of the form 'null/' (with a trailing forward slash) and that should not be replaced. Is there a way to replace only 'null' values while leaving 'null/' intact?

The sed one-liner:
sed 's#null\([^/]\|$\)#\1#g' file
should work for your requirement.
It searches pattern: null and followed by a non-slash char (or EOL),
replace with the followed non-slash char.
Thus, null/ won't be touched.

I think this command should be enough:
sed -e "s/null[^/]//g"

Related

sed command to replace a value in a file not using find and replace

I have a file with a string log.txt and inside the file i have multiple lines
line 1 text
line2/random/string/version:0.0.30
line 3 randome stuff
http://someurl:8550/
So currently I use sed to find and replace 0.0.30 to a new value like 0.0.31
with
sed -i s/0.0.30/0.0.31/g log.txt
The problem with this is I need to know the previous value.
Is there a way to always remove 0.0.30 from the string in the file and replace it with a new value ?
Maybe a indexof or a substring.
You can use a regex definition to match 0.0.30 and replace it with 0.0.31 as below. The --posix flag is to ensure no GNU dialects are applied and plain BRE (Basic Regular Expressions) library is used. Since \{2\} is a BRE syntax to match 2 occurrences of the digit.
sed -i --posix 's/[[:digit:]]\.[[:digit:]]\.[[:digit:]]\{2\}/0.0.31/' file
See explanation for regex here.

sed replace from csv include last character of search term

I am trying to replace a list of words found in a csv file with index markup (docbook). The csv is in this format:
testword[ -?],testword<indexterm><primary>testword</primary></indexterm>
This finds all occurrences of the testword with punctuation at the end. This part works. However, I need the final punctuation mark to be included in the replace part of the sed command.
sed -e 's/\(.*\)/s,\1,g/' index.csv > index.sed
sed -i -f index.sed file.xml
So e.g. This is a testword, in a test.
Would get replaced with This is a testword,<indexterm><primary>testword</primary></indexterm> in a test.
Problem is the string in the csv file that steers the proces, here you loose the punctuation.
Replacing the:
testword[ -?],testword<indexterm><primary>testword</primary></indexterm>
by:
testword\([ -?]\),testword\1<indexterm><primary>testword</primary></indexterm>
Would already solve your problem.

sed to replace a string which consist of a forwardslash

I'm trying to replace below specific lines in a file
/ACCOUNT/passwd=
/BMC/CONFIRMATION/PASSWORD=
I need help in preparing the sed command
The required output would look something like this
/ACCOUNT/passwd=-2$-$A88CA7BD3DADDDFFC
/TMC/CONFIRMATION/PASSWORD=-2$-$A88CA7BD3DADDDFFC
Any help is appreciated.
There is nothing special about the forward slash, except if you choose to use it as the delimiter in your sed command, so don’t:
sed 's,ACCOUNT/passwd=,ACCOUNT/passwd=-2$-$A88CA7BD3DADDDFFC,g'
And similar for other target strings.
Here I’ve used a comma as the delimiter. You can choose another character as you prefer.

Matching strings even if they start with white spaces in SED

I'm having issues matching strings even if they start with any number of white spaces. It's been very little time since I started using regular expressions, so I need some help
Here is an example. I have a file (file.txt) that contains two lines
#String1='Test One'
String1='Test Two'
Im trying to change the value for the second line, without affecting line 1 so I used this
sed -i "s|String1=.*$|String1='Test Three'|g"
This changes the values for both lines. How can I make sed change only the value of the second string?
Thank you
With gnu sed, you match spaces using \s, while other sed implementations usually work with the [[:space:]] character class. So, pick one of these:
sed 's/^\s*AWord/AnotherWord/'
sed 's/^[[:space:]]*AWord/AnotherWord/'
Since you're using -i, I assume GNU sed. Either way, you probably shouldn't retype your word, as that introduces the chance of a typo. I'd go with:
sed -i "s/^\(\s*String1=\).*/\1'New Value'/" file
Move the \s* outside of the parens if you don't want to preserve the leading whitespace.
There are a couple of solutions you could use to go about your problem
If you want to ignore lines that begin with a comment character such as '#' you could use something like this:
sed -i "/^\s*#/! s|String1=.*$|String1='Test Three'|g" file.txt
which will only operate on lines that do not match the regular expression /.../! that begins ^ with optional whiltespace\s* followed by an octothorp #
The other option is to include the characters before 'String' as part of the substitution. Doing it this way means you'll need to capture \(...\) the group to include it in the output with \1
sed -i "s|^\(\s*\)String1=.*$|\1String1='Test Four'|g" file.txt
With GNU sed, try:
sed -i "s|^\s*String1=.*$|String1='Test Three'|" file
or
sed -i "/^\s*String1=/s/=.*/='Test Three'/" file
Using awk you could do:
awk '/String1/ && f++ {$2="Test Three"}1' FS=\' OFS=\' file
#String1='Test One'
String1='Test Three'
It will ignore first hits of string1 since f is not true.

Replace 3 lines with another line SED Syntax

This is a simple question, I'm not sure if i'm able to do this with sed/awk
How can I make sed search for these 3 lines and replace with a line with a determined string?
<Blarg>
<Bllarg>
<Blllarg>
replace with
<test>
I tried with sed "s/<Blarg>\n<Bllarg>\n<Blllarg>/<test>/g" But it just don't seem to find these lines. Probably something with my break line character (?) \n. Am I missing something?
Because sed usually handles only one line at a time, your pattern will never match. Try this:
sed '1N;$!N;s/<Blarg>\n<Bllarg>\n<Blllarg>/<test>/;P;D' filename
This might work for you:
sed '/<Blarg>/ {N;N;s/<Blarg>\n<Bllarg>\n<Blllarg>/<test>/}' <filename>
It works as follows:
Search the file till <Blarg> is found
Then append the two following lines to the current pattern space using N;N;
Check if the current pattern space matches <Blarg>\n<Bllarg>\n<Blllarg>
If so, then substitute it with <test>
You can use range addresses with regular expressions an the c command, which does exactly what you are asking for:
sed '/<Blarg>/,/<Blllarg>/c<test>' filename