Shawn Y
Shawn Y

Reputation: 27

Find specific line from text file using two patterns then replace a variable string on that line

I have a large text file (myfile.txt), where for exactly one line, I'm trying to replace the value "0.999999999" with another number, let's say "0.111111111".

expression "if((CONDITION1==1),0.999999999,CATEGORY1)"

The line can be uniquely identified by looking up both the string in front of it and behind it (must be both together, or the pattern is not unique), or in this case

'expression "if((CONDITION1==1),'
and
',CATEGORY1)"'

After research a few other posts, I find the challenging part in my case to be

  1. identify a specific line by multiple pattern, and
  2. replacing a string that cannot be search on by itself (since it could change)

The first issue I see have been solved in other posts, but I'm stumped on the second one.

I tried a couple different ways, but none are producing the right thing, the closest one I got is :

sed -n '/if((CONDITION1==1).CATEGORY1)/{ s/\,*\,/\,0.111111111\,/p }' myfile.txt

Where I'm attempting to identify the strings by looking up part of the prefix and suffix strings, and then trying to replace everything between and including the two commas.

My questions are:

  1. what I'm doing wrong?
  2. is sed the best tool for this task, or would awk or perl do better? Thanks.

===============EDIT==============

I have updated my code based on @Ed 's version to be able to read in the value from an variable pulled from that file at the time code is run based on input. Hopefully it helps someone later:

#test.sh
month= $1
VAL= $(cat data_$month.dat | awk 'NR==2') 
echo "VAL is:" $VAL
sed -i 's/\(expression "if((CONDITION1==1),\)[^,]*\(,CATEGORY1)"\)/\1'"${VAL}"'\2/' file

Upvotes: 0

Views: 51

Answers (2)

user7712945
user7712945

Reputation:

if your data in 'd' file, try gnu sed:

sed -E 'h;s/expression "if\(\(CONDITION1==1\),([0-9.]+),CATEGORY1\)"/\1/;s/9/1/g;G;s/(.+)\n([^,]+,)[^,]+(,.+)/\2\1\3/' d

Upvotes: 0

Ed Morton
Ed Morton

Reputation: 203995

$ sed 's/\(expression "if((CONDITION1==1),\)[^,]*\(,CATEGORY1)"\)/\10.111111111\2/' file
expression "if((CONDITION1==1),0.111111111,CATEGORY1)"

Here's an example of why the part you don't capture should be [^,]* instead of .*:

$ cat file
expression "if((CONDITION1==1),0.999999999,CATEGORY1)"  # this is ",CATEGORY1)"
expression "if((CONDITION1==1),0.999999999,FOO)"        # this is not ",CATEGORY1)"

$ sed 's/\(expression "if((CONDITION1==1),\)[^,]*\(,CATEGORY1)"\)/\10.111111111\2/' file
expression "if((CONDITION1==1),0.111111111,CATEGORY1)"  # this is ",CATEGORY1)"
expression "if((CONDITION1==1),0.999999999,FOO)"        # this is not ",CATEGORY1)"

$ sed 's/\(expression "if((CONDITION1==1),\).*\(,CATEGORY1)"\)/\10.111111111\2/' file
expression "if((CONDITION1==1),0.111111111,CATEGORY1)"
expression "if((CONDITION1==1),0.111111111,CATEGORY1)"

Upvotes: 1

Related Questions