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 want to find and replace a value inside awk block.

Here is a sample input file to my script

P1
10,9:11/18013013582
,10:1
,167:0
,487:5/E.164
11,9:15/310410532169026
,10:60
,167:0
,487:4/IMSI
12,18:15/013329002130500
,19:0
15,9:10/9609610015
,10:1
,14:68
,167:0
,436:5/ABCDE
,487:5/E.164
16,87:1
17,9:10/8013765024
,10:1
,11:1
,12:0
,167:0
,487:5/E.164
23,9:11/13123149810
,10:1
,11:1
,167:0
,487:5/E.164
P3
42,3:1.
,4:3
,300:1.
43,3:1.
,4:3
,300:1.
44,3:0.
,4:7
,300:0.
45,5:0.3

And here is the piece of code that I am currently using,

nawk -v fname="${filename}" -F '/|:' '

    function isnum(x){return(x==x+0)}

    /P1/,/P3/{
            # Found start increment i reset variables go to next line
            if(/P1/){
                   ++i 
                   fid ="" 
                   count++
                   next
                }

            # Found end validate variable and print go to next line
            if(/P3/){
                printf "%s|",count
                printf "%s|",isnum(fid)?fid:"NULL"
                  next 
                }
            if(!fid && /36,59:*/)
                {
                    fid = $NF
                }
        ' ${filename} >>output.txt

Basically, I my input file will contain several P1/P3 blocks, I am taking one block at a time and finding out value from it. Now, what I want to basically do is change the value of first ,11:1 (i.e the one after 17,9 part) into 11:2 based on the value of 17,9:10/8013765024.

Please note there can be several ,11 before and after but those have to remain unchanged.

Please suggest how to proceed further. I am very new to both awk and sed.

Also, I tried writing a regular expression but could not figure out it properly. Here it is,

17[,0-9:\]*[\n]*,11
share|improve this question

migrated from stackoverflow.com Jul 24 at 1:57

This question came from our site for professional and enthusiast programmers.

    
you want to change the value which was present just after to 17,9:10/8013765024 –  Avinash Raj Jun 18 at 4:42
    
You want to prune this down to a really minimal example and explain how 2 is "based on" 8013765024. Is that a magic number we should be looking for, or a threshold value, or what are the conditions under which the first ,11:1 should be replaced? –  tripleee Jun 18 at 5:01
    
You cannot apply a regular expression across lines. You will need something like /^17[,0-9\:]*$/ { found=1 } found&/^,11/ { do things; found=0 } –  tripleee Jun 18 at 5:04
    
Your explanation is gibberish. Try rewording it. –  ooga Jun 18 at 5:07
    
Sorry for being unclear. 17,9:10/8013765024 ,10:1 ,11:1 see, if value after 17,9:10/ i.e. 8013765024 starts with 80 then I want to change this to +118013765024 and also the next ,11:1 value to ,11:2. I hope I am clear this time. Please let me know if I am not. –  Garvit Khandelwal Jun 18 at 5:40

3 Answers 3

Give a try to this awk command. Whenevre the awk find a number starting with 80 on column2, it gets the next line and then the next line and change it's value to ,11:2 print the other lines as it is.

$ awk -F/ '$2~/^80/{print; getline; print; getline; $1=",11.2"}1' file1.txt
P1
10,9:11/18013013582
,10:1
,167:0
,487:5/E.164
11,9:15/310410532169026
,10:60
,167:0
,487:4/IMSI
12,18:15/013329002130500
,19:0
15,9:10/9609610015
,10:1
,14:68
,167:0
,436:5/ABCDE
,487:5/E.164
16,87:1
17,9:10/8013765024
,10:1
,11.2
,12:0
,167:0
,487:5/E.164
23,9:11/13123149810
,10:1
,11:1
,167:0
,487:5/E.164
P3
42,3:1.
,4:3
,300:1.
43,3:1.
,4:3
,300:1.
44,3:0.
,4:7
,300:0.
45,5:0.3
share|improve this answer
    
Avinash I dont want to hard code the value 8013765024. I should be able to read the first two letters of 8013765024 and based on it I should be able to decide whether to change from ,11:1 to ,11:2. If first 2 digits are 80 then only i should change ,11:1 to ,11:2. To add to this I want 8013765024 also to be appended with +11 (+118013765024) –  Garvit Khandelwal Jun 18 at 6:11
    
You should avoid using getline read more here: awk.freeshell.org/AllAboutGetline –  Jotne Jun 18 at 6:12
    
@Jotne Please stop offering arbitrary "advice" about what not to do. It's (possibly) reasonable to use getline here. Of course, it's still very unclear what the OP actually wants, but getline is not the problem. –  ooga Jun 18 at 14:43
    
@AvinashRaj I don't see what the purpose of your f variable is. You set it, but never actually use it. –  ooga Jun 18 at 14:44
    
yes i set it to change the value of the second line after 17,9:10/8013765024 –  Avinash Raj Jun 18 at 14:49

Here is an awk solution:

$ awk -F '/|:' '
    $3 == "8013765024" {flag = 1}
    $0 == ",11:1" && flag {$2 = 2;flag = 0}
    1
' OFS=':' file
share|improve this answer

Here's a possible sed solution:

    sed  '/17,9:10\/80/,/11:1/ {
          s/8013765024/+118013765024/
          s/11:1/11:2/ }' file.txt

This starts the substitution after it finds 17,9:10/80 and first appends +11 to 8013765024 making it +118013765024 and it also replaces 11:1 with 11:2 for only the first occurrence of 11:1 (the range is inclusive)

Running diff on the output of the sed and the initial file shows:

    19c19
    < 17,9:10/+118013765024
    ---
    > 17,9:10/8013765024
    21c21
    < ,11:2
    ---
    > ,11:1

meaning that the only changes to the file are the addition of [+11] and the substitution of [11:1] to [11:2]. Let me know if this correct.

share|improve this answer

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.