在给定行号后查找第一个匹配的行号

时间:2013-04-16 22:02:03

标签: bash

我正在尝试编写一个bash脚本来删除ini文件中的多行。我有一个以下列方式配置的ini文件。

# There could be any text before the following text

[machine1.conn]
ipAddress=192.168.1.1
portNumber=11001

[machine2.conn]
ipAddress=192.168.1.2
portNumber=11002

[machine3.conn]
ipAddress=192.168.1.3
portNumber=11003

# There could be any text after the previous text

我想从ini文件中删除所有这些条目(包括属性)。

ini文件中可能有任意数量的“机器”条目,但是对于这个例子,我只显示3.括号内的标签在ini文件中是完全唯一的,但每个后面的属性显然不是。我已经有了一种方法来确定第一个[machine#.conn]以及最后一个的行号;让我们说这些分别分配给变量$firstMachineLineNum$lastMachineLineNum。我要做的是使用sed删除从$firstMachineLineNum到最后一台机器的portNumber行号的一系列行。我正朝这个方向前进,sed -i '$firstMachineLineNum,$lastMachinesPortNumLineNum$d' file.ini。为此,我需要一种方法来确定$lastMachinesPortNumLineNum,换句话说,portNumber在最后[machine#.conn]之后的第一个匹配的行号(在我的示例中为{{1} }})。理想情况下,我不必依赖于只添加2 [machine3.conn]

我怎样才能最好使用sed和/或grep提取这个行号?我一般来说这太复杂了,有一种更简单的方法吗?

3 个答案:

答案 0 :(得分:1)

试试这个单行:

awk -v RS="" -v ORS="\n\n" '!/machine[0-9]+\.conn/' file

小测试:

kent$  cat file
[foo_keep]
foo=foo

[machine1.conn]
ipAddress=192.168.1.1
portNumber=11001

[machine2.conn]
ipAddress=192.168.1.2
portNumber=11002

[machine3.conn]
ipAddress=192.168.1.3
portNumber=11003

[bar_keep]
bar=bar

[machine4.conn]
ipAddress=whatever
portNumber=11001

[machine5.conn]
ipAddress=whatever
portNumber=11002

[baz_keep]
hhh=hhh

输出

kent$   awk -v RS="" -v ORS="\n\n" '!/machine[0-9]+\.conn/' file
[foo_keep]
foo=foo

[bar_keep]
bar=bar

[baz_keep]
hhh=hhh

答案 1 :(得分:1)

如果文件如图所示,Sed会很容易地做到这一点(你想要移除的块中没有空白行):

sed '/^\[machine[0-9]\{1,\}\.conn\]/,/^\s*$/d' file

修改为接受以.conn结尾的任何名称:

sed '/^\[.*\.conn\]/,/^\s*$/d' file

针对可变目标线进行了修改:

machine='machine1'
sed '/^\['"$machine"'\.conn\]/,/^\s*$/d' file

答案 2 :(得分:0)

如果您只想排除这个特定的块,可以使用它:

awk 'NR < $firstline || NR > $lastline {print $0}' file.txt