Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash sed/awk在2个匹配之间插入行,但仅当没有其他模式时_Bash_Awk_Sed - Fatal编程技术网

Bash sed/awk在2个匹配之间插入行,但仅当没有其他模式时

Bash sed/awk在2个匹配之间插入行,但仅当没有其他模式时,bash,awk,sed,Bash,Awk,Sed,为了为Fail2Ban的自动安装和配置编写脚本,我需要一种修改a/etc/Fail2Ban/jail.local的方法。我的问题是,我需要在文件的特定部分中添加一行,但仅当该区域中不存在模式enabled=true时。还有一些地方不应该写入enable=true 以下SED工作正常,但不检查是否已经启用了enabled=true: sed '/\[apache-auth\]/{x;s/.*/./;x};/port/{x;/^.$/{x;s/^/enabled = true\n/;x};s/^/.

为了为Fail2Ban的自动安装和配置编写脚本,我需要一种修改a/etc/Fail2Ban/jail.local的方法。我的问题是,我需要在文件的特定部分中添加一行,但仅当该区域中不存在模式
enabled=true
时。还有一些地方不应该写入
enable=true

以下SED工作正常,但不检查是否已经启用了
enabled=true

sed '/\[apache-auth\]/{x;s/.*/./;x};/port/{x;/^.$/{x;s/^/enabled = true\n/;x};s/^/./;x}' -i /etc/fail2ban/jail.local 
sed '/\[apache-badbots\]/{x;s/.*/./;x};/port/{x;/^.$/{x;s/^/enabled = true\n/;x};s/^/./;x}' -i /etc/fail2ban/jail.local
sed '/\[apache-noscript\]/{x;s/.*/./;x};/port/{x;/^.$/{x;s/^/enabled = true\n/;x};s/^/./;x}' -i /etc/fail2ban/jail.local
sed '/^\[sshd\]/{x;s/.*/./;x};/port/{x;/^.$/{x;s/^/enabled = true\n/;x};s/^/./;x}' -i /etc/fail2ban/jail.local
更新添加请求的信息

原始文件

[sshd]

port    = ssh
logpath = %(sshd_log)s
backend = %(sshd_backend)s

[apache-auth]

port     = http,https
logpath  = %(apache_error_log)s


[apache-badbots]
# Ban hosts which agent identifies spammer robots crawling the web
# for email addresses. The mail outputs are buffered.
port     = http,https
logpath  = %(apache_access_log)s
bantime  = 172800
maxretry = 1


[apache-noscript]

port     = http,https
logpath  = %(apache_error_log)s
预期产出

[sshd]

enabled = true
port    = ssh
logpath = %(sshd_log)s
backend = %(sshd_backend)s
#
# HTTP servers
#

[apache-auth]

enabled = true
port     = http,https
logpath  = %(apache_error_log)s


[apache-badbots]
# Ban hosts which agent identifies spammer robots crawling the web
# for email addresses. The mail outputs are buffered.
enabled = true
port     = http,https
logpath  = %(apache_access_log)s
bantime  = 172800
maxretry = 1


[apache-noscript]

enabled = true
port     = http,https
logpath  = %(apache_error_log)s
英语不是我的母语,所以请不要判断我的拼写错误。我也不确定这是否是这个问题的正确站点。

这可能适合您(GNU-sed):

这将节存储在保留空间中,如果节不存在,则插入
enabled=true
,并打印出节

详细内容:

-r
-n
被激活,这使得前者的regexp更容易表达,后者的可选打印(类似grep,即必须存在命令
p
p

该命令由if-then-else组成

如果当前行以
[
开头并包含四个单词中的一个,然后是
]
,则将执行
{
}
之间的命令

打开
{
后的第一个命令是占位符,在满足文件结束条件时使用

x
意味着将模式空间(PS)与保持空间(HS)切换。Sed有,PS是当前行(减去其换行)读取的位置。HS是一个备用寄存器,由程序员自行决定使用

下一个命令
/./!bb
检查HS是否为空(如果这是第一次执行此代码,则为空),如果为空,则跳转到
:b
名称空间,忽略以下代码

现在知道HS包含一行或多行,检查这些行是否包含字符串
enabled=true
,如果不包含,则将字符串
enabled=true
插入以单词字符开头的第一行之前

无论匹配与否,HS都使用
p
命令打印

现在遇到分支名称空间
:b
,交换HS和PS,当前行替换HS
h
中的任何内容,然后删除
d
,从而结束对该行的处理


如果第一个regexp失败:当前行被追加到HS
H
并被删除
d
,除非它是最后一行,在这种情况下,处理通过命令
$ba
定向到名称空间
:a
。这覆盖了文件结束条件,在这种情况下,HS中的行将需要进行上述处理.

awk
救援

awk -v sections='sshd apache-auth apache-badbots apache-noscript' -v RS= -v ORS="\n\n" '
     BEGIN     {n=split(sections,a); 
                for(i=1; i<=n; i++) sec["["a[i]"]"]} 
     $1 in sec {$2 = "\nenabled = true\n"}1' file
awk-v sections='sshd apache auth apache badbots apache noscript'-v RS=-v ORS=“\n\n”'
开始{n=split(段,a);

对于(i=1;我能请你粘贴输入和预期的输出文件吗?@VIPINKUMAR我添加了输入文件和预期的输出如果你把样本减少到15行,而不是50行或其他任何行,那么你会有更多的人对你的问题感兴趣,因为他们理解你的要求所需的时间会少得多。你可以随时无论哪个方向都需要一个滚动条您的示例太大,您应该再次尝试创建一个(注意最小值)。感谢您的回答,但不幸的是,它在所有部分插入,而不仅仅是那些应该启用的部分。似乎我从文件中切出一点来创建一个最小的示例;)谢谢你的回答。你能解释一下这个字符串到底在做什么吗?因为我是初学者,我不太懂
awk -v sections='sshd apache-auth apache-badbots apache-noscript' -v RS= -v ORS="\n\n" '
     BEGIN     {n=split(sections,a); 
                for(i=1; i<=n; i++) sec["["a[i]"]"]} 
     $1 in sec {$2 = "\nenabled = true\n"}1' file