Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I have a file where each line contains a keyword (HELLO) and one or more numerical fields designated A1, A2, etc. The value in the numerical field is enclosed in brackets after the field name and is optional; if not present, it defaults to 0. Each field can contain multiple numbers separated by :; I only care about the first. I need to replace the keyword (HELLO) with `A1[X-Y+1]. Here is a quick example:

case1: my test is (HELLO) with some numbers (A1, A2, A3, A4)
case2: my test is (HELLO) with some numbers (A1[X:Y], A2, A3, A4)
case3: replaceit(something(HELLO)) sometext (single_bit_here, somedatahere[4], something, something,something,something) ;

In the first one, the field A1 isn't given a value, so 0 is assumed. 0+1=1, so the output is 1.

In the second case, A1 has a range X:Y, so the result is X-Y+1. Let's have X=10 and Y=3. Then "HELLO" will become 10-3+1=8.

Output:

case1: my test is (1) with some numbers (A1, A2, A3, A4)
case2: my test is (X-Y+1) with some numbers (A1[X:Y], A2, A3, A4)
case3: replaceit(something(1)) sometext (single_bit_here, somedatahere[4], something, something,something,something) ;

The code was modified a bit and it worked for all situations. awk 'BEGIN {FS="[[\]]"} { nFields=split($2,a,":") if(nFields ==2) n=1+a[1]-a[2] else n=1 gsub("data_width", n) } 1'

the following on question: I need to do the same "inline" replacement for all files in the same dir so I don't need to save back files. I'd like to use the perl script suggested below.

share|improve this question
    
Your specification says to only consider the first number, but your example output case3 suggests that A1[x:y] becomes x-y+1. –  Mikel Mar 3 at 0:28
    
Sorry that it should be [x:y] and x>y. –  user3342338 Mar 3 at 7:28

1 Answer 1

up vote 1 down vote accepted

The test data:

$ cat data
case1: my test is (HELLO) with some numbers (A1, A2, A3, A4)
case2: my test is (HELLO) with some numbers (A1[10:3], A2, A3, A4)
case3: replaceit(something(HELLO)) sometext (single_bit_here, somedatahere[4], something, something,something,something) ;

The Perl script:

#!/usr/bin/perl
use strict;
use warnings;

while (<>) {
    my $n = 1;
    $n = 1 + $1 - $2 if (/\([^\,)]*\[(\d+)(?::(\d+))?[^\)]*\)[^\)]*$/);
    s/HELLO/$n/;
    print;
}

The output:

$ ./the-script.pl < data
case1: my test is (1) with some numbers (A1, A2, A3, A4)
case2: my test is (8) with some numbers (A1[10:3], A2, A3, A4)
case3: replaceit(something(1)) sometext (single_bit_here, somedatahere[4], something, something,something,something) ;
share|improve this answer
    
I updated the spec so that HELLO need to be replaced by "x-y+1" instead of "x+1". I also found that your script didn't work properly when there are random space. –  user3342338 Mar 3 at 7:31
1  
@user3342338 - Updated answer for your updated specs (X-Y+1). Regarding "random space": impossible to fix without exact info. You cannot just introduce "random" without stuff breaking. Your question should reflect all possible cases of "random". –  grebneke Mar 3 at 10:08
    
awk 'BEGIN {FS="[[\]]"} { nFields=split($2,a,":") if(nFields ==2) n=1+a[1]-a[2] else n=1 gsub("data_width", n) } 1' <datain.txt this worked ok. you can modify the perl script. –  user3342338 Mar 3 at 22:59
    
@user3342338 - "modify the perl script"? –  grebneke Mar 3 at 23:12

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.