bash - grep 与以下以空格开头的行匹配

标签 bash awk sed grep

问题

假设我有一个包含以下内容的文件:

lmtp_bind_address (default: empty)
       The LMTP-specific version of the smtp_bind_address configuration parameter.  See there for details.

       This feature is available in Postfix 2.3 and later.

lmtp_bind_address6 (default: empty)
       The LMTP-specific version of the smtp_bind_address6 configuration parameter.  See there for details.

       This feature is available in Postfix 2.3 and later.

lmtp_body_checks (default: empty)
       The LMTP-specific version of the smtp_body_checks configuration parameter. See there for details.

       This feature is available in Postfix 2.5 and later.

我想获取以“lmtp_bind_address6”开头的行以及以下所有以空格开头的行:

lmtp_bind_address6 (default: empty)
       The LMTP-specific version of the smtp_bind_address6 configuration parameter.  See there for details.

       This feature is available in Postfix 2.3 and later.

我如何在 bash 中执行此操作?

背景信息

我正在离开 Centos 7 并在 Debian 8 上设置 Postfix。因此,我打算阅读 Postfix 版本 2.11.3 的 7255 行长的“man 5 postconf”。为了加快速度,我想在联机帮助页中对 Postfix 选项进行分组,这些选项涵盖相同的内容但适用于不同的协议(protocol),例如:

smtpd_tls_mandatory_ciphers
lmtp_tls_mandatory_ciphers
smtp_tls_mandatory_ciphers
tlsproxy_tls_mandatory_ciphers

正如您在上面看到的,这四个选项中的每一个都可以选择 TLS 密码,但适用于不同的协议(protocol)(SMTPD、LMTP 等)。

首先,我按以下方式对 Postfix 选项进行了分组:

postconf | awk -F"=" '{print $1}' | sed 's/ //g' | rev | sort | \
rev > postconf_options.txt

然后,我将联机帮助页转储到一个文件中:

man 5 postconf > postconf_manpage.txt

现在,我想遍历分组列表并将包含以下以空格开头的行的每个匹配项转储到第三个文件:

cat postconf_options.txt | while read I; do
  grep -w "^$I" postconf_manpage.txt
done > postconf_manpage_grouped.txt

上面的 grep 命令只给出匹配的行,而不是后面以空格开头的行。

解决方案

为了能够使用变量,我在 sed 中使用了双引号。这是来自 hek2mgl 的解决方案的完整过程:

postconf | awk -F"=" '{print $1}' | sed 's/ //g' | rev | sort | rev > postconf_options.txt
man 5 postconf > postconf_manpage.txt
cat postconf_options.txt | while read I; do sed -n "/^$I/{p;:a;n;/^[[:space:]]\|^$/{p;ba}}" postconf_manpage.txt; done > postconf_manpage_grouped.txt

最佳答案

我会使用 sed:

sed -n '/^lmtp_bind_address6/{p;:a;n;/^[[:space:]]\|^$/{p;ba}}' file
  • /^lmtp_bind_address6/ 匹配搜索模式
  • {p;:a;n;/^[[:space:]]\|^$/{p;ba}} 确实使用 p,定义了一个标签 :a ,它充当跳转标记,能够遍历以空格开头的行。 n 会将另一行读入模式缓冲区。 /^[[:space:]]\|^$/ 匹配以空格空行开头的行。如果是这种情况,该行将使用 p 打印,我们将使用 ba 跳回到 a

关于bash - grep 与以下以空格开头的行匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38203009/

相关文章:

linux - command_not_found_handler 在 mac 中不工作

linux - 如何更改默认的 Eclipse 控制台?

c - 如何在C中运行shell命令

bash - 如何使用 sed(或 awk)进行链接规范化,获取文件名?

bash - 搜索多个精确模式以替换为 sed 或 awk

bash - 如何停止使用 ruby​​ Sass 并开始使用 Dart-sass。分别卸载-安装

bash - 如何查找两个列表之间的校验和匹配(但不在两个列表内)?

python - 使用 awk 实用程序实现的场景

linux - Apache - 最后一小时的日志

Makefile 教程中令人困惑的 Sed 单行代码