【问题标题】:pass bash regex pattern as a part of bigger regex pattern in awk将 bash 正则表达式模式作为 awk 中更大的正则表达式模式的一部分传递
【发布时间】:2018-11-10 02:26:04
【问题描述】:

我正在尝试在我的脚本中执行此操作:

 CONTEXT_PAT1="\[[gG][lL][oO][bB][aA][lL]\]"

 awk -v pat1="$CONTEXT_PAT1" 'f;/^[:space:]*pat1[:space:]*$/{f=1}' ${CONFIG_FL}

当我在调试模式下运行它时,我看到了这种情况:

 ++ awk -v 'pat1=\[[gG][lL][oO][bB][aA][lL]\]' 'f;/^[:space:]*pat1[:space:]*$/{f=1}

预期是:

 ++ awk -v 'pat1=\[[gG][lL][oO][bB][aA][lL]\]' 'f;/^[:space:]\[[gG][lL][oO][bB][aA][lL]\][:space:]*$/{f=1}

我怎样才能做到这一点?我在stackoverflow中浏览了一些文章

https://unix.stackexchange.com/questions/120788/pass-shell-variable-as-a-pattern-to-awk?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa

但这是当你使用正则表达式来 awk 时,而不是将其视为更大正则表达式的一部分。

如何做到这一点?

【问题讨论】:

  • 能否请您在您的帖子中添加一些输入和预期输出示例,以便我们也可以测试我们的代码。

标签: regex bash shell awk scripting


【解决方案1】:

编辑:要从 sh -x 跟踪中获得您期望的输出,请阅读此答案。要创建正确的 awk 代码,请阅读 @ghoti 的答案。

$ 扩展不会发生在单引号 (') 内,但会发生在双引号 " 内。试试:

CONTEXT_PAT1="\[[gG][lL][oO][bB][aA][lL]\]"

awk 'f;/^[:space:]'"${CONTEXT_PAT1}"'[:space:]*$/{f=1}' "${CONFIG_FL}"

shell 不会为您扩展 *pat1。假设您所说的“调试模式”是sh -x

【讨论】:

  • 不确定我是否在这里遗漏了什么,-v 在这里没有任何值?
  • @RavinderSingh13 已修复 ;)
  • 我可以建议你不要这样做吗?以这种方式嵌入变量通常被认为是不好的做法。使用-v 传递变量更安全。当您按照此答案的建议执行操作时,一些小而意外的事情会导致您的脚本崩溃,或者更糟糕的是,容易受到攻击。
  • @ghoti True,但这满足了问题中sh -x 的预期输出。
  • 不要这样做,这是错误的做法。在给定特定输入的情况下产生预期输出的代码是正确答案的起点点,而不是终点。
【解决方案2】:

实际上,您可以匹配变量或函数。它只是一个隐含的简写,其中一个 RE 旨在匹配整行,其中没有将变量嵌入到更大的 RE 中的机制。因此,您可能想要明确,并使用 RE 运算符 ~

对于你的例子,我会用这样的东西:

$ pat1="[[][gG][lL][oO][bB][aA][lL][]]"
$ awk -v pat1="$pat1" 'BEGIN{re="^[[:space:]]*" pat1 "[[:space:]]*$"} f; $0~re{f=1}' file.cfg

甚至,

$ awk -v pat1="$pat1" 'f; $0~sprintf("^[[:space:]]*%s[[:space:]]*$",pat1) {f=1}' file.cfg

我什至可以通过省去传递不区分大小写的正则表达式的麻烦来进一步简化这个东西的使用:

$ pat1="global"
$ awk -v pat1="$pat1" 'f; tolower($0) ~ sprintf("^[[:space:]]*[[]%s[]][[:space:]]*$",tolower(pat1)) {f=1}' file.cfg

【讨论】:

  • 这是正确的答案,只要您的正则表达式(它一个正则表达式,而不是“模式” - 模式适用于被子和毛衣,在软件中我们应该尝试要清楚和具体地了解我们正在使用的构造)不包含您不想解释的反斜杠。如果确实如此,则在参数列表中传递正则表达式。见cfajohnson.com/shell/cus-faq-2.html#Q24
  • @ghoti 它实际上不起作用。我正在放置调试行(我的意思是sh -x)。第一个:++ awk -v 'pat1=[[][gG][lL][oO][bB][aA][lL][]]' 'BEGIN{re="^[[:space:]]*" pat1 "[[:space:]]*$"} f; $0~re{f=1}' /etc/samba/smb.conf。对于第二个:++ awk -v 'pat1=[[][gG][lL][oO][bB][aA][lL][]]' 'f; $0~sprintf("^[[:space:]]*%s[[:space:]]*$",pat1) {f=1}' /etc/samba/smb.conf,我敢肯定第三个扩展...
  • @dig_123,请记住,sh -x 仅向您显示 shell 行是如何扩展的,它不能帮助您调试 awk 脚本或查看您的数据是如何被解释的。当我写这篇文章时,我使用了我创建的示例输入,因为您的问题中没有,我的代码可以使用它。如果您可以在问题示例输入中添加它不起作用,我很乐意帮助您找出原因。
猜你喜欢
  • 2012-05-17
  • 1970-01-01
  • 1970-01-01
  • 2014-09-15
  • 1970-01-01
  • 2013-11-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多