sed multiline substitution if a condition holds


 
Thread Tools Search this Thread
Top Forums Shell Programming and Scripting sed multiline substitution if a condition holds
# 1  
Old 10-14-2011
sed multiline substitution if a condition holds

Hi.

I have the following text file (more precisely a Matlab script):

dummy1 = 5; varx = 'false'; dummy2 = 6;
% ... some general commands
% ...
dummy3 = 7; vary = 'option1'; dummy4 = 8;

Using sed I want to do the following action:

IF varx = 'false'
vary='NEW_VALUE_1'
ELSEIF varx='true'
vary='NEW_VALUE_2'
ELSE
nothing to do
END


varx/y might not be at the beginning/end of the line, as in the example above, and a generic number of spaces is before/after the '=' sign. An unknown number of lines is between the lines containing varx/y (see ...some general commands). Looking at the example above, sed should return the following:

dummy1 = 5; varx = 'false'; dummy2 = 6;
% ... some general commands
% ...
dummy3 = 7; vary = 'NEW_VALUE_1'; dummy4 = 8;


Thanks
Paolo
# 2  
Old 10-14-2011
I'm not sure I understand your conditions. Is the ELSE ever going to be executed except at the start of the file (i.e. before we encounter the first varx assignment)?

Put another way, what output would you expect from:
Code:
dummy3 = 7; vary = 'option1'; dummy4 = 8;
dummy1 = 5; varx = 'false'; dummy2 = 6;
dummy3 = 7; vary = 'option1'; dummy4 = 8;
dummy3 = 7; vary = 'option1'; dummy4 = 8;
dummy1 = 5; varx = 'true'; dummy2 = 6;
dummy3 = 7; vary = 'option1'; dummy4 = 8;

(with whatever in-between the varx/vary lines)


EDIT: A possible (and rather messy Smilie) awk solution:
Code:
#  cat xx.awk
BEGIN {
        FS=";";
        xval=-1;
        if (NEWVAL1=="") NEWVAL1="'optionA'";
        if (NEWVAL2=="") NEWVAL2="'optionB'";
}
$2 ~ /varx *= *'false'/ {
        xval=0;
        print;
}
$2 ~ /varx *= *'true'/ {
        xval=1;
        print;
}
$2 ~ /vary *= */ {
        if (xval==1) {
                printf ("%s; vary = %s", $1, NEWVAL2);
                x=3;
        }
        else if (xval==0) {
                printf ("%s; vary = %s", $1, NEWVAL1);
                x=3;
        }
        else {
                printf ("%s", $1);
                x=2;
        }
        for (i=x;i<=NF;i++) {
                printf ("; %s", $i);
        }
        printf ("\n");
}
$2 !~ /var[xy] *= */ {
        print;
}

Code:
# cat xx.txt
dummy3 = 7; vary= 'option1'; dummy4 = 8;
% whatever
dummy1 = 5; varx = 'false'; dummy2 = 6;
% whatever
% whatever
dummy3 = 7; vary =  'option1'; dummy4 = 8;
dummy3 = 7; vary='option1'; dummy4 = 8;
% whatever
dummy1 = 5; varx  = 'true'; dummy2 = 6;
% whatever
% whatever
dummy3 = 7; vary ='option1'; dummy4 = 8;
% whatever

Code:
# awk -f xx.awk xx.txt
dummy3 = 7;  vary= 'option1';  dummy4 = 8;
% whatever
dummy1 = 5; varx = 'false'; dummy2 = 6;
% whatever
% whatever
dummy3 = 7; vary = 'optionA';  dummy4 = 8;
dummy3 = 7; vary = 'optionA';  dummy4 = 8;
% whatever
dummy1 = 5; varx  = 'true'; dummy2 = 6;
% whatever
% whatever
dummy3 = 7; vary = 'optionB';  dummy4 = 8;
% whatever


Last edited by CarloM; 10-14-2011 at 01:04 PM..
This User Gave Thanks to CarloM For This Post:
# 3  
Old 10-14-2011
If you insists on using sed:
Code:
sed "/varx =/h
/vary = /{
G
s/\(.*vary = '\)[^']*\('.*\)\n.*varx = 'false'.*/\1NEW_VAL_1\2/
t # optional
s/\(.*vary = '\)[^']*\('.*\)\n.*varx = 'true'.*/\1NEW_VAL_2\2/
}" file

This User Gave Thanks to binlib For This Post:
# 4  
Old 10-16-2011
Thanks, your solution answered my question. However, you point out another problem that may appear,i.e., what happens if vary precedes varx. To better explain this point, let me express the problem in its original form, hence slightly different from the simplified one of the previous post.
I'm upgrading my personal software and for compatibility reasons I have to change all my old scripts. Striclty speaking I have the following code:

Quote:
var.applyfield1 = true; % var.applyfield1 can be true or false
% .... some line codes
var.field1type = 'type1'; % var.field1type can be one of the strings: 'type1','type2',...,'typeN'
Please, note that var.applyfield1 is a struct variable.

IF var.applyfield1 = true, at the output I want:

Quote:
var.FIELD1.APPLY = 'type1';
% .... some code lines
therefore both variable assignments regarding var.applyfield1 and var.field1type must be removed and substituted (before or after the "%... some code lines", it doesn't matter) with the new variable var.FIELD1.APPLY

ELSE, IF var.applyfield1 = false, I want:

Quote:
var.FIELD1.APPLY = '';
% .... some line codes
same as before but with a different value for var.FIELD1.APPLY (empty string).

The new problem that I was mentioning at the beginning of this reply is that awk or sed must operate as well even if var.applyfield1 and var.field1type are exchanged. For instance, with;


Quote:
var.field1type = 'type1'; % var.field1type can be one of strings: 'type1','type2',...,'typeN'
% ... some code lines
var.applyfield1 = true; % var.applyfield1 can be true or false
I want the same kind of substitution, namely:

Quote:
var.FIELD1.APPLY = 'type1';
% ...some code lines
The assignments to var.field1type and var.applyfield1 can be safely assumed to appear once in the script.

If possible, I would prefer a solution based on sed because such replacement is just one of many, which can be easily handled with the option -e.

Thanks again,
Paolo
# 5  
Old 10-17-2011
Will all substitutions involve fieldNtype and applyfieldN? (and do all occurances of those need to be replaced?)

Also, does it matter if you get:
Code:
% ...some code lines
var.FIELD1.APPLY = 'type1';

(i.e. with the new statement replacing the last of an apply/type pair) rather than the other way around?

Last edited by CarloM; 10-17-2011 at 08:26 AM.. Reason: typo
# 6  
Old 10-17-2011
Yes. Please note that field1type and applyfield1 are just generic names. You can assume that all occurances have to be replaced; if you find easier to substitute just the first occurance, for me is good as well (because each occurance appears once in my scripts).
# 7  
Old 10-17-2011
Quote:
Originally Posted by plsrn
Please note that field1type and applyfield1 are just generic names.
Obviously, but what I'm trying to determine is if there's a common pattern to the names that we can use to perform the substitution. Do they all have the form varname.somethingtype / samevarname.applysamesomething (with bold parts as fixed literals), or anything similar?
Login or Register to Ask a Question

Previous Thread | Next Thread

9 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

sed multiline problem

I'm trying to replicate the sed output on p.108 of Sed&Awk,by Doughery & Robbins, 2nd edition. I'm on a Windows 10 Surface Pro, running Cygwin for 64-bit versions of Windows. Input text saved in text file called data_p108.txt: Consult Section 3.1 in the Owner and Operator Guide for a... (9 Replies)
Discussion started by: prooney
9 Replies

2. Shell Programming and Scripting

[sed]: Substitute a string with a multiline value

Dear all, I try to replace a string of characters in a file (MyFile.txt) by a multiline value of the variable "Myvar": $ cat MyFile.txt DESCRIPTION '@TargetTable SCHEMA' ( @InputFlowDef ); $ The content of Myvar: $ echo "$Myvar" col1 , col2 , col3 $ (4 Replies)
Discussion started by: dae
4 Replies

3. Shell Programming and Scripting

Multiline sed

Hi guys, I am fairly comfortable with using the sed command if the string to be replaced is all on a single line. I was wondering is it possible to use sed command in a multiline way ? Say for example I have the below string on 2 different lines: { "key": "brandNameA", ... (3 Replies)
Discussion started by: Junaid Subhani
3 Replies

4. Shell Programming and Scripting

sed failing with multiline html loaded with metacharacters

I have html files (newlines ending in linefeed) with metacharacter-laden multiline text I want to replace. To matters more complicated, the first line may appear elsewhere in the file, so I need these lines as a block. I can replace individual lines, but am failing to come up with anything that can... (2 Replies)
Discussion started by: mauricev
2 Replies

5. UNIX for Dummies Questions & Answers

Need Multiline sed help!!

Hey everyone, I'm new to sed and I need to create a script for inserting one line of code at the beginning of every method in a Xcode project (over 6,000 methods). Each method Structure is (+ or -) (Various declarations-- could span multiple lines) ({) I've tried for days, any guidance would be... (2 Replies)
Discussion started by: jimmyz
2 Replies

6. Shell Programming and Scripting

Using sed to pattern match within a particular multiline block and take action

Hi all, This is my first post, so please go easy if I broke some rules. Not accustomed to posting in forums... :) I'm looking for help on pattern matching within a multiline block and looking to highlight blocks/block-ids that do NOT contain a particular pattern. For example an input file... (5 Replies)
Discussion started by: tirodad
5 Replies

7. UNIX for Dummies Questions & Answers

sed multiline pattern match

How can I write a script that takes a cisco config file and outputs every occurrence of two, or more, pattern matches through the whole config file? For example, out of a config file, i want to print out every line with interface, description and ip address through the whole file, and disregard... (3 Replies)
Discussion started by: knownasthatguy
3 Replies

8. Shell Programming and Scripting

Multiline pattern search using sed or awk

Hi friends, Could you please help me to resolve the below issue. Input file :- <Node> <username>abc</username> <password>ABC</password> <Node> <Node> <username>xyz</username> <password>XYZ</password> <Node> <Node> <username>mnp</username> ... (3 Replies)
Discussion started by: haiksuresh
3 Replies

9. Shell Programming and Scripting

delete multiline string from file using sed.

Hi, I have file which has the following content... GOOD MORNING **********WARNING********** when it kicks from the kickstart, sshd daemon should start at last. (WHEN KICKING ITSELF, NOT AFTER KICKING). /etc/rc3.d/S55sshd ( run level specification for sshd is 55, now I would want to... (4 Replies)
Discussion started by: skmdu
4 Replies
Login or Register to Ask a Question