【问题标题】:awk: exclude pattern, match only expression, sort, uniqawk:排除模式,仅匹配表达式,排序,uniq
【发布时间】:2015-12-03 06:12:52
【问题描述】:

我正在尝试处理 500,000 行文本。我下面的代码有效,但对我来说似乎非常不足。我想通过用 awk 完成这个来测试这个理论,看看我是否有任何时间节省。使用各种变量在我的脚本中复制此代码块。此处节省的时间相当于脚本结束时节省的 10 倍。但是,我真的很难用 awk 实现这一目标。

脚本:

_regex_ipv4_ip_='((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])'

_regex_ipv4_cidr_='(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))'

grep -v '^#' ${tmp}/url_* | grep -Eho "${_regex_ipv4_ip_}|${_regex_ipv4_cidr_}" | sort | uniq >${tmp}/ipv4

我该怎么做,只有 awk... 搜索多个文件。 排除行匹配模式。 将 bash 变量带入 awk。 使用正则表达式模拟“grep -o”。 对结果进行排序(如果它们只是在 bash 中对 'uniq' 进行排序,则不必在意) 模仿 uniq 将结果写入文件

输入文件如下所示

#Comment
http://192.168.0.1/whatever #Comment
192.168.0.1
http://192.168.0.1/whatever/whatever
192.168.0.1 #Comment
192.168.0.0/16
192.168.0.0/16 #Comment

删除重复项后的输出...

192.168.0.1 192.168.0.0/16

更新:1

这就是我现在的位置......

这也完全符合我的要求..

_regex_ipv4_ip_='192.168.0.1'
_regex_ipv4_cidr_='192.168.0.0/16'

awk -v exclude='#' -v include="${_regex_ipv4_ip_}" -v include2="${_regex_ipv4_cidr_}" '($0 !~ exclude) && match($0,include) && !seen[substr($0,RSTART,RLENGTH)]++ || match($0,include2) && !seen[substr($0,RSTART,RLENGTH)]++' /home/master/Desktop/t_*

但是我不能正确地将变量中包含的正则表达式正确地携带到 awk 中。

_regex_ipv4_ip_='((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])'
_regex_ipv4_cidr_='(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))'

【问题讨论】:

  • 是否有理由why 需要使用awk 来做到这一点?你展示的管道对你有用吗?
  • 您所描述的在 awk 中是微不足道的,但显示了几个示例输入文件和相关的输出,以便我们可以正确获取详细信息(例如,它是每个文件唯一还是在您想要的所有文件中都是唯一的)
  • 上述管道确实有效。考虑到我用不同的表达式和模式多次执行此操作,我想看看是否还有其他代码可以使过程更快。我认为 awk 可能是一个更好的起点,而不是管道和调用这么多命令。上面代码中发生的事情是我的表达式被保存为一个变量,以便在脚本的其他地方使用。 1.) 忽略以“#”开头的行 2.) 仅打印匹配的 ip 地址表达式或 ip cidr 表达式。3.) 删除所有文件中的重复项并将结果保存到输出文件。

标签: regex bash sorting awk uniq


【解决方案1】:

你想要的是这样的:

awk -v exclude='whatever' -v include='whatever' '
($0 !~ exclude) && match($0,include) && !seen[substr($0,RSTART,RLENGTH)]++
' file1 file2 ... fileN

但在您发布示例输入/输出之前,我们无法填写详细信息。

【讨论】:

  • 我想知道您是否对此有答案:How to print own script name in awk?。我无法想象其他人知道如何做到这一点:)
  • print ENVIRON["_"] 可以在某些 awks 中使用,但我不知道它的便携性如何。不过,与往常一样,我不会在 shell 脚本中使用 shebang 执行 awk 脚本,因为它只会剥夺您可能的功能(例如,使用-v 设置命令行变量的能力,例如awk -v cmd="$0" 'script' "$@") .我添加了对该问题的答案。
猜你喜欢
  • 1970-01-01
  • 2011-03-01
  • 1970-01-01
  • 2022-07-28
  • 1970-01-01
  • 1970-01-01
  • 2014-09-15
  • 2016-04-25
相关资源
最近更新 更多