我的输入文件包含如下数据
acb/xyz/row<t>
acb/xyz/row<t>
abc/xyz/row<b>
abc/xyz/row<b>
abc/xyz/row<0>
abc/xyz/row<0>
abc/xyz/row<1>
abc/xyz/row<1>
abc/xyz/row<2>
abc/xyz/row<2>
abc/xyz/row<3>
abc/xyz/row<3>
abc/xyz/row<4>
abc/xyz/row<4>
所以我希望输出如下所示:
#Sector Top
acb/xyz/row<t>
acb/xyz/row<t>
#Sector Bottom
abc/xyz/row<b>
abc/xyz/row<b>
#Sector 0
abc/xyz/row<0>
abc/xyz/row<0>
#Sector 1
abc/xyz/row<1>
abc/xyz/row<1>
#Sector 2
abc/xyz/row<2>
abc/xyz/row<2>
#Sector 3
abc/xyz/row<3>
abc/xyz/row<3>
#Sector 4
abc/xyz/row<4>
abc/xyz/row<4>
- 上面显示的每个扇区包含多行,这里我只显示了每个扇区 2 行。
- 有顶部、底部和从0到30个扇区,这里我最多显示了4个扇区。
我尝试使用 sed 命令来获取其中一个扇区:
sed '/row<1>/i #Sector 1' myfile
这给了我这样的输出:
#Sector 1
abc/xyz/row<1>
#Sector 1
abc/xyz/row<1>
我不需要在每场比赛前换行,只需要在所有部分的第一场比赛前换行。
答案1
使用任何 awk:
$ cat tst.awk
BEGIN {
FS = "[<>]"
map["t"] = "Top"
map["b"] = "Bottom"
}
{
sector = $(NF-1)
if ( sector != prev ) {
print "#Sector", (sector in map ? map[sector] : sector)
prev = sector
}
print
}
$ awk -f tst.awk file
#Sector Top
acb/xyz/row<t>
acb/xyz/row<t>
#Sector Bottom
abc/xyz/row<b>
abc/xyz/row<b>
#Sector 0
abc/xyz/row<0>
abc/xyz/row<0>
#Sector 1
abc/xyz/row<1>
abc/xyz/row<1>
#Sector 2
abc/xyz/row<2>
abc/xyz/row<2>
#Sector 3
abc/xyz/row<3>
abc/xyz/row<3>
#Sector 4
abc/xyz/row<4>
abc/xyz/row<4>
答案2
您可以使用N;P;D
循环来执行此操作,并且仅在行号确实更改时sed
插入行:#Sector
sed -E 'N;P;/^(.*)\n\1/D;s/.*(\n.*)(row<)([0-9bt])*>/#Sector \3\1\2\3>/;P;D'
现在我们需要为top
andbottom
部分添加处理,如下所示:
sed -E -e '1i #Sector top' -e 'N;P;/^(.*)\n\1/D;s/.*(\n.*)(row<)([0-9bt])*>/#Sector \3\1\2\3>/;s/#Sector b/&ottom/;P;D'
详细解释:
- 选项
-E
是使输出更具可读性。相反,您还可以为这些(…)
部分添加八个反斜杠 1i #Sector top
只需添加第一个扇区标头- 现在我们总是附加
N
ext 行以始终一起处理两行并P
打印第一行 /^(.*)\n\1/
是第一行重复的表达式,因此没有理由插入节标题,因此我们D
删除第一行以继续第二行- 现在一些正则表达式魔法:
s/.*(\n.*)(row<)([0-9bt])*>/#Sector \3\1\2\3>/
用节标题和第三()
对中提取的行号替换第一行(已经打印!) - 最后简单地将更改
b
为bottom
s/#Sector b/&ottom/
P
并通过打印第一行并D
删除它以继续第二行来关闭循环
答案3
使用GNUsed
$ sed -Ez 's/(\S+row<([^>]*)>)(.*\1)?/#Sector \2\n&/g;s/\<t\>/Top/;s/\<b\>/Bottom/' input_file
#Sector Top
acb/xyz/row<t>
acb/xyz/row<t>
#Sector Bottom
abc/xyz/row<b>
abc/xyz/row<b>
#Sector 0
abc/xyz/row<0>
abc/xyz/row<0>
#Sector 1
abc/xyz/row<1>
abc/xyz/row<1>
#Sector 2
abc/xyz/row<2>
abc/xyz/row<2>
#Sector 3
abc/xyz/row<3>
abc/xyz/row<3>
#Sector 4
abc/xyz/row<4>
abc/xyz/row<4>
答案4
下面的脚本将在 bash shell 中运行
#!/bin/bash
awk 'BEGIN{ FS="/" }
{a=$3;
if(a != b)
print "Sector " substr(a,5,1)"\n" a
else
print a;
b=$3}' myfile.txt