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
# 8  
Old 10-17-2011
varname and samevarname are for sure the same. Concerning somethingtype and applysomething in principle they could be different. For instance I have exactly these names:

Quote:
var.applypol = true;
var.polmethod = 'cma';
that I'd like to transform in:

Quote:
var.pol.apply = 'cma';
Concerning your "(i.e. with the new statement replacing the last of an apply/type pair) rather than the the way around?", the answer is yes, you can replace the last assignment.
# 9  
Old 10-17-2011
Well, I spent a couple of hours playing in sed and couldn't find a way - but then I'm not very good with sed!

I did manage to create a solution of sorts with awk.

It uses a csv containing the variable name, 'apply' fieldname, 'type' fieldname, and the replacement field name to use. E.g.:
Code:
#  cat xf.txt
var,applypol,polmethod,pol.apply
var2,fldapply,fldtype,fld.apply
var4,apply,type,apply

Bash script - creates an awk (actually gawk) program using the csv data, and then calls it:
Code:
cat xx.sh
#!/bin/sh

AWKFILE=`basename $0`_$$.awk

[[ -f $AWFILE ]] && rm $AWKFILE

while IFS=',' read VN AN TN RN
do
        cat >> $AWKFILE <<EOFILE
/$VN\.$TN *= *'[^']*'/ {
   match (\$0, "(.*)$VN.$TN *= *'([^']*)';(.*)",statements);

   ${VN}_type=statements[2];

   if ( ${VN}_apply != "" ) {
      if ( ${VN}_apply == "true" ) {
         printf ("%s$VN.$RN = '%s'; %s\n", statements[1], ${VN}_type, statements[3]);
      }
      else {
         printf ("%s$VN.$RN = \"; %s\n", statements[1], statements[3]);
      }
   }
   else {
      printf ("%s%s\n", statements[1], statements[3]);
   }
}
/$VN\.$AN *= *'[^']*'/ {
   match (\$0, "(.*)$VN.$AN *= *'([^']*)';(.*)",statements);

   ${VN}_apply=statements[2];

   if ( ${VN}_type != "" ) {
      if ( ${VN}_apply == "true") {
         printf ("%s$VN.$RN = '%s'; %s\n", statements[1], ${VN}_type, statements[3]);
      }
      else {
         printf ("%s$VN.$RN = \"; %s\n", statements[1], statements[3]);
      }
   }
   else {
      printf ("%s%s\n", statements[1], statements[3]);
   }
}
EOFILE

        if [ -z "$exclstr" ]
        then
                exclstr="$VN.$AN|$VN.$TN"
        else
                exclstr=$exclstr"|$VN.$AN|$VN.$TN"
        fi

done < $2

cat >> $AWKFILE <<EOFILE
\$0 !~ /($exclstr) *= *'[^']*'/ {
   print;
}
EOFILE

gawk -f $AWKFILE $1

rm $AWKFILE


Which seems to work:
Code:
# cat xx.txt
% whatever 1
dummy3 = 7; var.polmethod= 'optionA'; dummy4 = 8;
% whatever 2
dummy1 = 5; var.applypol = 'false'; dummy2 = 6;
dummy1 = 5; var2.fldapply = 'false'; dummy2 = 6;
% whatever 3
dummy3 = 7; var2.fldtype= 'option1'; dummy4 = 8;
% whatever 4
dummy3 = 7; var3.fldtype =  'optionB'; dummy4 = 8;
% whatever 5
dummy1 = 5; var3.fldapply  = 'true'; dummy2 = 6;
% whatever 6
% whatever 7
% whatever 8
dummy1 = 5; var4.apply = 'true'; dummy2 = 6;
% whatever 9
% whatever 10
% whatever 11
% whatever 12
dummy3 = 7; var4.type ='option2'; dummy4 = 8;
% whatever 13

Code:
# ./xx.sh xx.txt xf.txt
% whatever 1
dummy3 = 7;  dummy4 = 8;
% whatever 2
dummy1 = 5; var.pol.apply = ";  dummy2 = 6;
dummy1 = 5;  dummy2 = 6;
% whatever 3
dummy3 = 7; var2.fld.apply = ";  dummy4 = 8;
% whatever 4
dummy3 = 7; var3.fldtype =  'optionB'; dummy4 = 8;
% whatever 5
dummy1 = 5; var3.fldapply  = 'true'; dummy2 = 6;
% whatever 6
% whatever 7
% whatever 8
dummy1 = 5;  dummy2 = 6;
% whatever 9
% whatever 10
% whatever 11
% whatever 12
dummy3 = 7; var4.apply = 'option2';  dummy4 = 8;
% whatever 13

I'm sure there must be an easier way though (and I suspect enough variables to replace will cause something in there to fail horribly).

Last edited by CarloM; 10-17-2011 at 01:47 PM..
This User Gave Thanks to CarloM For This Post:
# 10  
Old 10-18-2011
Smilie It works great!!! Only three minor problems:

1) I receive the following error message

./xx.sh: 5: [[: not found

2) 'false' and 'true' are actually false and true, without apices. For instance:
var.applypol = false;

3) Output like:
var.pol.apply = ";
should be:

var.pol.apply = '';
with two single apices ' in place of one quote ".
# 11  
Old 10-19-2011
Don't have access to a box right now to test it, but these changes should work:

1. Change the hashbang to #!/bin/bash (on my system /bin/sh is a link to bash). Or just change the [[ to a full if.

2. Change
Code:
/$VN\.$AN *= *'[^']*'/ {
   match (\$0, "(.*)$VN.$AN *= *'([^']*)';(.*)",statements);

to
Code:
/$VN\.$AN *= *[^ ]*/ {
   match (\$0, "(.*)$VN.$AN *= *([^ ]*) *;(.*)",statements);

3. Change
Code:
printf ("%s$VN.$RN = \"; %s\n", statements[1], statements[3]);

to
Code:
printf ("%s$VN.$RN = ''; %s\n", statements[1], statements[3]);

(two places)
This User Gave Thanks to CarloM For This Post:
# 12  
Old 10-20-2011
Ok, now it works. I slighlty modified your final suggestion using the following code. Thanks a lot for your (really impressive) effort in helping me!

Quote:
#!/bin/sh

AWKFILE=`basename $0`_$$.awk

[[ -f $AWFILE ]] && rm $AWKFILE

while IFS=',' read VN AN TN RN
do
cat >> $AWKFILE <<EOFILE
/$VN\.$TN *= *'[^']*'/ {
match (\$0, "(.*)$VN.$TN *= *'([^']*)';(.*)",statements);

${VN}_type=statements[2];

if ( ${VN}_apply != "" ) {
if ( ${VN}_apply == "true" ) {
printf ("%s$VN.$RN = '%s'; %s\n", statements[1], ${VN}_type, statements[3]);
}
else {
printf ("%s$VN.$RN = ''; %s\n", statements[1], statements[3]);
}
}
else {
printf ("%s%s\n", statements[1], statements[3]);
}
}
/$VN\.$AN *= *[^;]*/ {
match (\$0, "(.*)$VN.$AN *= *([^;]*) *;(.*)",statements);

${VN}_apply=statements[2];

if ( ${VN}_type != "" ) {
if ( ${VN}_apply == "true") {
printf ("%s$VN.$RN = '%s'; %s\n", statements[1], ${VN}_type, statements[3]);
}
else {
printf ("%s$VN.$RN = ''; %s\n", statements[1], statements[3]);
}
}
else {
printf ("%s%s\n", statements[1], statements[3]);
}
}
EOFILE

if [ -z "$exclstr" ]
then
exclstr="$VN.$AN|$VN.$TN"
else
exclstr=$exclstr"|$VN.$AN|$VN.$TN"
fi

done < $2

cat >> $AWKFILE <<EOFILE
\$0 !~ /($exclstr) *= *[^;]*/ {
print;
}
EOFILE

gawk -f $AWKFILE $1

rm $AWKFILE
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