0

我正在尝试编写一个 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. 为此,我需要一种方法来确定AFTER 最后$lastMachinesPortNumLineNum一个匹配的第一个匹配的行号(在我的示例中是)。理想情况下,我不必仅仅依靠将 2 添加到portNumber[machine#.conn][machine3.conn]$lastMachineLineNum.

我怎样才能最好地使用 sed 和/或 grep 提取此行号?总的来说,我是不是把它弄得太复杂了,还有一种更简单的方法?

4

3 回答 3

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
于 2013-04-16T22:13:10.293 回答
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
于 2013-04-16T22:22:38.260 回答
0

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

awk 'NR < $firstline || NR > $lastline {print $0}' file.txt
于 2013-04-16T22:15:27.233 回答