【问题标题】:awk variable assignment statement explanation needed需要awk变量赋值语句解释
【发布时间】:2013-09-14 05:47:06
【问题描述】:

好的,直截了当,这里是代码,为了便于阅读,我对代码进行了一些格式化:

awk '{
t=$0   ; 
$0=t   ; $0=//           ; print "$0=//           ; value of $0 is ",$0
$0=t   ; $0=/./          ; print "$0=/./          ; value of $0 is ",$0
$0=t   ; $0=/*/          ; print "$0=/*/          ; value of $0 is ",$0
$0=t   ; $0=/**/         ; print "$0=/**/         ; value of $0 is ",$0
$0=t   ; $0=/[0-9]/      ; print "$0=/[0-9]/      ; value of $0 is ",$0
$0=t   ; $0=/[a-z]/      ; print "$0=/[a-z]/      ; value of $0 is ",$0
$0=t   ; $0=/[0-9][a-z]/ ; print "$0=/[0-9][a-z]/ ; value of $0 is ",$0
$0=t   ; $0=/5/          ; print "$0=/5/          ; value of $0 is ",$0
$0=t   ; $0=/55/         ; print "$0=/55/         ; value of $0 is ",$0
$0=t   ; $0=/x/          ; print "$0=/x/          ; value of $0 is ",$0
$0=t   ; $0=/5x/         ; print "$0=/5x/         ; value of $0 is ",$0
$0=t   ; $0=/x5/         ; print "$0=/x5/         ; value of $0 is ",$0
$0=t   ; $0=/xoo/        ; print "$0=/xoo/        ; value of $0 is ",$0
$0=t   ; $0=/500/        ; print "$0=/500/        ; value of $0 is ",$0
}'<<<"5x"

我得到了这个输出:

$0=//           ; value of $0 is  1
$0=/./          ; value of $0 is  1
$0=/*/          ; value of $0 is  0
$0=/**/         ; value of $0 is  1
$0=/[0-9]/      ; value of $0 is  1
$0=/[a-z]/      ; value of $0 is  1
$0=/[0-9][a-z]/ ; value of $0 is  1
$0=/5/          ; value of $0 is  1
$0=/55/         ; value of $0 is  0
$0=/x/          ; value of $0 is  1
$0=/5x/         ; value of $0 is  1
$0=/x5/         ; value of $0 is  0
$0=/xoo/        ; value of $0 is  0
$0=/500/        ; value of $0 is  0

我不明白为什么会得到这个输出。我以为 awk 会抱怨赋值语句,但它没有......当我做$0=/xxx/ 时,awk 似乎正在做奇怪的正则表达式匹配检查?也就是说,$0=/pattern/$0=$0~/pattern/ 相同?

然后我做了这个测试:

kent$  echo "xx"|awk '{y="777";y=/x/;print y}'                                                                                                                              
1

kent$  echo "xx"|awk '{y="777";y=/7/;print y}'                                                                                                                              
0

看来,foo=/pattern/foo=$0~/pattern/ 相同

但我不确定...在文档/手册页中找不到信息。

我在这里@SO 回答 awk 问题时发现了它。

我用我的 awk 测试过:

kent$  awk --version|head -1
GNU Awk 4.1.0, API: 1.0 (GNU MPFR 3.1.2, GNU MP 5.1.2)

如果有人可以解释我,我很感激。提前致谢。

编辑

在做了更多测试后,事实证明(再次,不确定,因为我没有在文档中找到它),{...},单独的/pattern/ 是@ 的缩写形式987654332@ 与{...} 外部相同,如/patter/{do something} 。所以我们可以这样做:

kent$  echo "xx"|awk '{if(/x/)print "ok"}'                                                                                                                                  
ok

我不知道这是否是 awk 脚本语法的标准功能。如果它适用于所有 awk 实现。我仍在搜索手册和手册页...

【问题讨论】:

  • 这是一个很好的谜题,我现在看不到答案,但我并不感到惊讶 $0=// 和所有其他人都通过了。这不就像你在c 中犯了一个错误,比如while(i=j){j=func(...); .. },当你真正打算while(i==j) { ... } 时。 D(我知道,这不是一个很好的例子)。使用不同的输入,或者就像带有/dev/null 的END 块会改变什么吗?我假设如果您使用初始 print "#dbg:$0="$0,您会在那里看到正确的值吗?祝你好运!
  • BSD awk 是一样的,除了 /*//**/ 是语法错误。

标签: awk gawk


【解决方案1】:

/regexp/ 只是$0 ~ /regexp/ 的简写

var = ($0 ~ /regexp/) 将比较结果分配给 var,1 为真,否则为零。

$0 = ($0 ~ /regexp/) 将 $0 和 /regexp/ 的比较结果赋值给 $0

$0 = ($0 ~ //) 将 $0 赋值为在 $0 中查找空字符串的结果,总是存在的,所以条件为真所以结果为 1

$0 = // 也是如此

$0 = /*/ 正在寻找 $0 中的文字 *,但不存在因此结果为零。

$0 = /**/ 正在寻找文字 * 在 $0 中重复零次或多次,其中有零次,因此结果为 1。

没有神秘,没有什么奇怪的......

【讨论】:

  • 谢谢 Ed,我在我的问题中添加了一个 EDIT。但是我以前从未使用过/见过的这种形式:'{if(/pat/){dostuff}}' 它是否适用于所有 awk impl。 ?
  • 我关于 'awk' 的书也这么说:/pat/$0~/pat/ 的简写,if ($0~/pat/)if (/pat/) 相同。
  • 谢谢版。 +1!这很有趣:echo "20"|awk '{a=5(/10/);print a}' 将输出50
【解决方案2】:

这里并不神秘,您只是将$0 的值设置为评估的正则表达式匹配的值。首先评估右侧,如果该行与正则表达式匹配,则结果为 True ,即1,否则结果为 False ,即0

【讨论】:

  • 鉴于/*/ 为0,我假设它将/**/ 解释为/\**/
  • /**/ 是零次或多次出现字符 *。他的输入中有零个,所以条件$0 ~ /**/ 为真。
  • @Kevin。正确的。像 *+? 这样的 RE 重复元字符就是 RE 中的第一个字面字符。
  • @EdMorton BSD awk 的行为并非如此。它在任何地方都有记录吗?
  • @sudo_O 感谢您的回答。从输出来看,是的,它就是这样工作的,我也在我的问题中写了它。我知道/pat/{do stuff}', but I don't find (so far) any documentation, that is saying {if(/pat/)...}` 与{if($0~/pat/)..} 相同
猜你喜欢
  • 2019-06-22
  • 2014-06-16
  • 1970-01-01
  • 2017-08-13
  • 2021-08-13
  • 2017-06-04
  • 2020-06-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多