【问题标题】:Is there a way to obtain the current pattern searched in an AWK script?有没有办法获得在 AWK 脚本中搜索的当前模式?
【发布时间】:2014-12-14 19:20:57
【问题描述】:

基本思想是这样的。假设您想使用 awk 从管道中搜索文件中的多个模式:

 ... | awk -f - '{...}' someFile.txt

* '...' 只是一些代码的缩写
* '-f -' 表示模式取自管道

有没有办法知道在 awk 脚本中的每个时刻搜索哪种模式
(就像您知道 $1 是第一个字段一样,是否有类似 $PATTERN 的内容包含当前模式 搜索或获得类似内容的方法?
详细说明:
如果我有 2 个文件:
someFile.txt 包含:

1  
2  
4  

patterns.txt 包含:

1  
2  
3  
4

运行这个命令:

cat patterns.txt |awk -f - '{...}' someFile.txt

我应该在大括号之间键入什么,以便只有 patterns.txt 中的模式
has not been match in someFile.txt 打印出来了?(这种情况下patterns.txt中的数字3不匹配)

【问题讨论】:

  • 要获取“只有patterns.txt 中没有在someFile.txt 中匹配的模式”,请尝试grep -v someFile.txt patterns.txt
  • 我想在这里明确使用awk。
  • 您是否正确使用awk的选项。根据手册页-f 指定要执行的脚本,因此以下- 只是从标准输入获取脚本,而不是将其作为第一个非选项参数(您也提供)。将patterns.txt 传递给awk 的IHMO 将导致将someFile.txt 的每一行传递给标准输出的次数与patterns.txt 中的非零模式一样多。这可以通过将两个文件作为正常输入提供给awk 并提供适当的脚本来解决。帽子会有帮助吗?

标签: regex awk sh gawk


【解决方案1】:

patterns.txt作为标准输入提供并且使用awk完成处理的要求下:

$ cat patterns.txt | awk 'FNR==NR{p=p "\n" $0;next;} p !~ $0' someFile.txt -
3  

这是使用 GNU awk 测试的。

说明

我们希望从 patterns.txt 中删除与 someFile.txt 中的行匹配的任何内容。为此,我们首先读取 someFile.txt 并从中创建模式。接下来,我们只打印 patterns.txt 中与 someFile.txt 中的任何模式都不匹配的行。

  • FNR==NR{p=p "\n" $0;next;}

    NRawk 到目前为止已读取的行数,FNRawk 迄今为止从当前文件读取的行数。因此,如果FNR==NR,我们仍在读取第一个命名文件:someFile.txt。我们将所有这些行保存在换行符分隔的变量p 中。然后我们告诉awk 跳过剩余的命令并跳转到next 行。

  • p !~ $0

    如果我们到了这里,那么我们现在正在命令行上读取第二个命名文件,即- 用于标准输入。此布尔条件的计算结果为真或假。如果为真,则打印该行。如果不是,则跳过。换句话说,上面是 awk 的隐晦简写:

    p !~ $0 {print $0}
    

【讨论】:

  • 这个答案在输出中似乎对我有用。你介意解释一下这里使用的语法吗?
【解决方案2】:
cmd | awk 'NR==FNR{pats[$0]; next} {for (p in pats) if ($0 ~ p) delete pats[p]} END{ for (p in pats) print p }' - someFile.txt

【讨论】:

    【解决方案3】:

    awk 中的另一种方式

    cat patterns.txt | awk 'NR>FNR&&!($0 in a);{a[$0]}' someFile.txt -
    

    【讨论】:

      猜你喜欢
      • 2023-01-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-04
      • 2013-06-10
      • 1970-01-01
      • 2022-07-21
      • 1970-01-01
      相关资源
      最近更新 更多