【问题标题】:Order of operations in awk?awk中的操作顺序?
【发布时间】:2014-11-25 15:20:26
【问题描述】:

我正在尝试使用 awk 做两件事。我想将一个列表分成三个单独的列表,并将每个列表的 1 或 2 列转换为正则表达式。当我将 awk 传递给自身时,即在列表中选择我的项目,然后使用 awk 进行替换,它会将 1 附加到列表项。

我认为我不需要将 awk 传递给自身,而是在一次调用 awk 时完成所有这些操作。

AH??0*,*,ARRAY RESISTIVITY,RESISTIVITY
AHD*,*,MEASURED DEPTH,REFERENCE
AI*,*,ACOUSTIC IMPEDANCE COMPRESSIONAL,GEOPHYSICAL SYNTHETICS
AI_AVG_HOR_SIG,*,ACOUSTIC IMPEDANCE,ACOUSTIC
*,FOO,BAR,BLEH

列表一将是类似于第 4 行的行,第一列中没有通配符,替换第 2 列中的通配符。

列表 2 将用于单独列表中的第 1,2 和 3 行,并且需要对第 1 列和第 2 列进行替换。

最后,我需要在单独的列表中为第 5 行做类似的事情。

我可以这样做。

第 4 行:awk -F \, '$1!~/([\*\?])/' file.txt
第 1-3 行:awk -F \, '$1~/([\*\?])/' file.txt
第 5 行:awk -F \, '$1~/^\*$/' file.txt

我的潜艇是 * => .* 和 ? => [0-9]。

当我尝试像 awk -F \, 'gsub(/\*/,".*",$2) $1!~/([\*\?])/' OFS=, file.txt 这样使用 gsub 时,列表返回时会出现意想不到的结果。关于堆栈操作,我觉得 awk 有一个基本的东西我不明白。

停下来!

【问题讨论】:

  • 您需要将gsub 放在一个动作块中。 {gsub(...)}。现在它是一种模式。所以它执行它的任务,然后告诉 awk 打印当前行。如果您只希望在 $1~.... 模式匹配时使用该 gsub,那么您希望将 gsub 放入该模式的操作块中(并且您还需要添加 print)。
  • 这对我有用。我现在唯一的问题是这个awk -F \, '$1~/[\*\?]/ && $1!~/^\*$/' {gsub(/\*/,".*",$1) ; gsub(/\?/,"[0-9]",$1) ; gsub(/\*/,".*",$2);print} OFS=, file.txt 会导致错误。可能是因为我正在做两个正则表达式比较。不知道如何解决这个问题。
  • 您过早地结束了 awk 脚本(单引号字符串)。单引号需要在最后的;print} 之后而不是$1!~/^\*$/ 之后。
  • 感谢伊坦!我最终使用:awk 'BEGIN{FS=","}{if($1~/[\*\?]/ && $1!~/^\*$/){ gsub(/\*/,".*",$1); gsub(/\?/,"[0-9]",$1); gsub(/\*/,".*",$2); print; } }' OFS=, file.txt
  • 您可以将测试提升到一个动作而不是使用if (),但我不知道这在任何方面都很重要,但在风格上。我还会选择一种设置变量的方法,BEGIN 或从命令行,但这只是样式。

标签: awk gawk


【解决方案1】:

我在这里写的不是你问题的解决方案。这只是一个练习 重组您的版本...(供您完成:)。 仍然缺少一些@Etan 明智的建议。 (风格问题可以为我们节省大量时间)。

awk(或任何单行解决方案)会因为它超过大约 30 个字符而变得混乱。 行情等变得困难。

您可以(应该?)将其写入具有适当缩进、cmets、垂直对称性的文件 (a.awk):

#!/usr/bin/gawk -f

BEGIN                          { FS="," ; OFS=","     }

$1 ~ /[\*\?]/ && $1 !~ /^\*$/  { gsub(/\*/, ".*"   ,$1 );
                                 gsub(/\?/, "[0-9]",$1 );
                                 gsub(/\*/, ".*"   ,$2 );
                                 print; }

并将其用作awk -f a.awk inputfile

当前行为是:

echo 'AH??0*,*,ARRAY RESISTIVITY,RESISTIVITY
AHD*,*,MEASURED DEPTH,REFERENCE
AI*,*,ACOUSTIC IMPEDANCE COMPRESSIONAL,GEOPHYSICAL SYNTHETICS
AI_AVG_HOR_SIG,*,ACOUSTIC IMPEDANCE,ACOUSTIC
*,FOO,BAR,BLEH' | awk -f /tmp/a1

AH[0-9][0-9]0.*,.*,ARRAY RESISTIVITY,RESISTIVITY
AHD.*,.*,MEASURED DEPTH,REFERENCE
AI.*,.*,ACOUSTIC IMPEDANCE COMPRESSIONAL,GEOPHYSICAL SYNTHETICS

【讨论】:

  • 我很感激。我能够以 Etan 的 cmets 为食,并获得更多关于 awk 的信息,因为我不必经常使用它。但是,在潜入之后,我可以看到它会在未来为我节省大量时间......
猜你喜欢
  • 2016-02-15
  • 2015-09-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-07
相关资源
最近更新 更多