Bash sed/awk在2个匹配之间插入行,但仅当没有其他模式时
为了为Fail2Ban的自动安装和配置编写脚本,我需要一种修改a/etc/Fail2Ban/jail.local的方法。我的问题是,我需要在文件的特定部分中添加一行,但仅当该区域中不存在模式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/^/.
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,当前行替换HSh
中的任何内容,然后删除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