我有一个文件,其中的模式(例如:RotX)在类似的上下文中重复多次。我需要在每行的开头插入一个特定的文本(例如:Rot-X),该文本位于每个模式匹配之前的五行:
...
_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);
}
...
应该成为
...
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);
}
...
这可以使用 sed 或 awk 来完成吗?
预先非常感谢您的帮助
答案1
使用简单的 2 遍方法:
$ 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);
}
...
答案2
使用vim
vim -c "g/RotX/norm 5kIRot-x" -c "wq" file.txt
使用ed:来自@steeldriver
printf '%s\n' 'g/(RotX)/-5s/^/Rot-X/' 'wq' | ed -s file.txt
如果大括号{
, 不需要正好在上面 4 行,但其他格式相同,
vim -c "g/RotX/norm [{kIRot-X" -c "wq" file.txt
printf "%s\n" 'g/RotX/?^{$?-1s/^/Rot-X/' 'wq' | ed -s file.txt
答案3
使用 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);
}