我正在尝试编写一个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提取这个行号?我一般来说这太复杂了,有一种更简单的方法吗?
答案 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