1

I have a file in which a pattern (eg: RotX) is repeated many times in a similar context. I need to insert a specific text (eg: Rot-X) at the start of every line which is located five lines before every pattern match:

...
_face_641
{
 type wall;
 nFaces 6;
 startFace 63948413;
 inGroups 1(RotX);
}
_face_821
{
 type wall;
 nFaces 3;
 startFace 63948419;
 inGroups 1(RotX);
}
_face_67
{
 type wall;
 nFaces 3;
 startFace 63948422;
 inGroups 1(RotX);
}
...

should become

...
Rot-X_face_641
{
 type wall;
 nFaces 6;
 startFace 63948413;
 inGroups 1(RotX);
}
Rot-X_face_821
{
 type wall;
 nFaces 3;
 startFace 63948419;
 inGroups 1(RotX);
}
Rot-X_face_67
{
 type wall;
 nFaces 3;
 startFace 63948422;
 inGroups 1(RotX);
}
... 

Could this be done using sed or awk ?

Many thanks in advance for your help

asked Jul 26, 2022 at 14:02
2
  • 1
    Does the pattern change? For example, could you just preface every line that starts with _ with Rot-X? Or does the pattern within your parentheses vary such that it's not always Rot-X where RotX is found 5 lines later? Commented Jul 26, 2022 at 14:27
  • yes the pattern varies Commented Jul 26, 2022 at 15:16

3 Answers 3

1

Using a simple 2-pass approach:

$ awk 'NR==FNR{ if (/RotX/) nrs[NR-5]; next } FNR in nrs{ 0ドル="Rot-X" 0ドル } 1' file file
...
Rot-X_face_641
{
 type wall;
 nFaces 6;
 startFace 63948413;
 inGroups 1(RotX);
}
Rot-X_face_821
{
 type wall;
 nFaces 3;
 startFace 63948419;
 inGroups 1(RotX);
}
Rot-X_face_67
{
 type wall;
 nFaces 3;
 startFace 63948422;
 inGroups 1(RotX);
}
...
answered Jul 26, 2022 at 17:46
1
  • 1
    I tried the 2-pass approach. It works perfectly. Wonderful ! A great thank you to you Ed ! Commented Jul 27, 2022 at 10:26
1

Using vim

vim -c "g/RotX/norm 5kIRot-x" -c "wq" file.txt

Using ed: From @steeldriver

printf '%s\n' 'g/(RotX)/-5s/^/Rot-X/' 'wq' | ed -s file.txt

If the braces {, need not be exactly 4 lines above but otherwise same format,

vim -c "g/RotX/norm [{kIRot-X" -c "wq" file.txt
printf "%s\n" 'g/RotX/?^{$?-1s/^/Rot-X/' 'wq' | ed -s file.txt
answered Jul 26, 2022 at 20:01
2
  • 1
    ... or similarly using ed, printf '%s\n' 'g/(RotX)/-5s/^/Rot-X/' 'wq' | ed -s file.txt Commented Jul 26, 2022 at 22:08
  • @steeldriver cool Thanks!. :) Didn't know ed had the g command Commented Jul 27, 2022 at 2:01
0

A single pass with awk:

# insert_before_match.awk
{
 p6=p5
 p5=p4
 p4=p3
 p3=p2
 p2=p1
 p1=0ドル
 if (0ドル ~ /RotX/) {
 print "Rot-X"p6
 print p5
 print p4
 print p3
 print p2
 print p1
 print "}"
 print ""
 }
}

$ awk -f insert_before_match.awk infile

Rot-X_face_641
{
 type wall;
 nFaces 6;
 startFace 63948413;
 inGroups 1(RotX);
}
Rot-X_face_821
{
 type wall;
 nFaces 3;
 startFace 63948419;
 inGroups 1(RotX);
}
Rot-X_face_67
{
 type wall;
 nFaces 3;
 startFace 63948422;
 inGroups 1(RotX);
}
answered Jul 27, 2022 at 3:19

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.