1

I want to search each record (records are defined by blank lines) in a file for the pattern NAME#AAAA. If it matches, then insert an # in front of the record's age and insert a line age NIL at the end of the record.

INPUT FILE:

NAME#AAAA
STD 1
SEC A
AGE 5

NAME#BBBB
STD 2
SEC B
AGE 6


NAME#CCCC
STD 3
SEC C
AGE 7

NAME#AAAA
STD 4
AGE 9


NAME#AAAA
STD 7
SEC A
AGE 12

EXPECTED OUTPUT

NAME#AAAA
STD 1
SEC A
#AGE 5
AGE NIL

NAME#BBBB
STD 2
SEC B
AGE 6

NAME#CCCC
STD 3
SEC C
AGE 7


NAME#AAAA
STD 4
#AGE 9
AGE NIL


NAME#AAAA
STD 7
SEC A
#AGE 12
AGE NIL
  • Ok Fine.. now its clearly. Sorry once again. – user4432340 Apr 19 '16 at 14:48
  • No worries. We do things a little differently from similar sites, it takes some getting used to. You might want to take the tour or read the help center to understand how the site works. Welcome aboard! – terdon Apr 19 '16 at 14:50
0

Whenever you see records separated by blank lines ("paragraphs", if you like), Perl's "paragraph mode" is often a good solution:

$ perl -00lpe 'if(/NAME#AAAA/){s/\bAGE\s/#$&/; s/$/\nAGE NIL/;}' file
NAME#AAAA
STD 1
SEC A
#AGE 5
AGE NIL

NAME#BBBB
STD 2
SEC B
AGE 6

NAME#CCCC
STD 3
SEC C
AGE 7

NAME#AAAA
STD 4
#AGE 9
AGE NIL

NAME#AAAA
STD 7
SEC A
#AGE 12
AGE NIL

Explanation

  • -00 : this activates perl's paragraph mode, where each "paragraph" (group of non-blank lines until a blank one) is treated as a "line".
  • -l : removes trailing newlines from each input record (each paragraph) and adds a newline to each print call. -pe : print each input record aftrer applying the script given by -e to it.

So, those flags make perl read over the input file, applying the script to each record, and then printing the result. The script itself does:

  • if(/NAME#AAAA/) : if this record matches NAME#AAAA.
  • s/\bAGE\s/#$&/ : The s/foo/bar/ is the substitution operator. It will replace foo with bar. Here, I am replacing AGE with itself preceded by a #. The \b matches word boundaries, and will exclude things like ADAGE from the match. The $& is a special variable and means "whatever was matched. So, s/\bAGE\s/#$&/ will replace AGE with #AGE.
  • s/$/\nAGE NIL/ : The $ matches the end of the record. So replacing it with something else will append to the end of the record. This command appends AGE NIL to the end of the matched record.

Note that all operations here are case sensitive. If you need case insensitive matching use this instead:

perl -00lpe 'if(/NAME#AAAA/i){s/\bAGE\s/#$&/i; s/$/\nAGE NIL/i;}' file
  • wow!!! That's great,.. Thank you so much :):):) i have one more scenario. Just like this.. shall i ask it here or open a new thread? in the same scenario, if i have to move the #AGE to the top of the paragraph and insert the new line just like this. Also, i need the vice versa of it(to revert back the changes). – user4432340 Apr 19 '16 at 16:10
  • @user4432340 you're welcome :). Please do take a moment to take the tour though, it only takes a minute and will explain how this site works. Yes, if you have a new question, post it separately. You can link back to this one for reference, if you need to. If this answer solved your issue, you can accept it by clicking on the check mark to the left. That will mark the question as answered and is the way thanks are expressed on the Stack Exchange sites. – terdon Apr 19 '16 at 16:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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