awk 1和{print}之间的区别?

时间:2016-08-30 08:18:09

标签: awk

awk change once per file的评论让我觉得ApplicationUser1在awk中是相同的。但事实并非如此。

{print}

比较(这是我想要的btw):

awk '/^\S/ {core=0} /^_core/ {core=1} !core 1' views.view.who_s_online.yml|head
uuid: 50715f68-3b13-4a15-8455-853110fd1d8b
langcode: en
status: true
dependencies:
  module:
    - user
_core:
  default_config_hash: DWLCIpl8ku4NbiI9t3GgDeuW13KSOy2l1zho7ReP_Bg
id: who_s_online
label: 'Who''s online block'

2 个答案:

答案 0 :(得分:3)

awk程序的结构是一系列条件和动作:

condition { action }

condition的默认值为1(true),因此总是会发生没有条件的操作:

{ action } # is equivalent to
1 { action }

默认操作为print,因此您经常会在awk脚本中看到1而不是{ print }

但是,在您的脚本中,您的条件为!core 1。这将否定core的值,将其强制转换为字符串并与字符串"1"连接。非空字符串始终为true,因此将打印每条记录。

如果您只想打印core为假的记录,那么您可以单独使用!core作为条件。

答案 1 :(得分:3)

是的,它们是一样的。

这些表达式完全等效:

awk '1' file
awk '{print}' file
awk '42' file
awk '2342352' file
awk '{print $0}' file

为什么呢?因为True条件会触发awk的默认操作:打印当前记录;也就是{print $0}

现在,这里发生了什么?

您正以不同的方式使用它们。在一个案例中,您说:

awk '{things...} !core 1' file
#                ^^^^^^^

在这种情况下,!core没有做任何事情。它只读awk '{things...} 1' file。或者更好地看一下Tom Fenech's explanation

您可以执行seq 10 | awk '/5/ {core++} 1'seq 10 | awk '/5/ {core++} !core'来测试它。两者都返回从1到10的所有数字。相反,您希望使用seq 10 | awk '/5/ {core++} !core'从1到4进行打印。

还要注意与

的不同之处
awk '{things...} !core; 1' file
#                     ^

通过这个半冒号,这将触发!core中的操作(即,打印当前记录-line-如果核心评估为False),然后1将使无论任何条件,它都会打印所有记录。因此seq 10 | awk '/5/ {core++} !core; 1'将打印1到10,打印1到4两次。

另一种情况你说:

awk '{things...} !core {print}' file
#                ^^^^^^^^^^^^^

如下所示:如果核心评估为False,则执行print

他们背后的原因是什么?

这是因为awk适用于语法condition { action },当{ action }包含在默认操作中时{print $0}可以被{print $0}抑制:condition。这样,只要您希望始终触发操作,您就可以说1或只使用42部分使用True条件,例如varprint,一个已经设置为正值的变量,等等。

然后,这对于使awk代码更具惯用性也很有用:如果将变量作为标志使用,可以说core只要标志设置为a就会触发awk '/5/ {core++} core' awk '/5/ {core++} { if (core > 0) {print $0}}' awk '{ if ($0~/5/) {core++}} { if (core > 0) {print $0}}' 真实情况,与您在代码中使用[pattern] { action } pattern [{ action }] … function name(args) { … } … 同样如此。这样,这两个awk表达式是等价的:

/foo/  { }     match foo, do nothing — empty action
/foo/          match foo, print the record — omitted action

了解使用惯用代码如何让它看起来更好? ;)

检查GNU Awk User's Guide → 7.3 Actions以获得更多技术性解释(可能比我的措辞更好!):

  

awk程序或脚本由一系列规则和功能组成   穿插的定义。 (功能稍后描述。见   用户定义。)规则包含模式和动作   哪个(但不是两个)可以省略。行动的目的是为了   告诉awk一旦找到匹配的模式,该怎么做。因此,在   大纲,一个awk程序通常看起来像这样:

 @Override
    public void onTestFailure(ITestResult result) {
        System.out.println("***** Error "+result.getName()+" test has failed *****");
        String methodName=result.getName().toString().trim();
        takeScreenShot(methodName);
     

一个动作由一个或多个awk语句组成,括在括号中   (“{...}”)。每个语句都指定了一件事。声明是   以换行符或分号分隔。一个动作周围的大括号必须   即使操作只包含一个语句,也可以使用它   根本不包含任何陈述。但是,如果省略该操作   完全,省略括号。省略的动作相当于   '{print $ 0}':

<!--show more start-->
<div class="expand-section-button compensate-padding-left"
     ng-if="ctrl.isShowMore(ctrl.facetGroup)"
     (click)="ctrl.toggleMoreFacets(ctrl.facetGroup)"
     aria-label="{{::ctrl.facetGroup.name}}">

    <md-button class="button-as-link link-alt-color zero-margin"
               aria-label="{{'facets.facet.facet_'+ ctrl.facetGroup.name | translate}}">

            <span class="bold-text"
                  translate="nui.facets.showmore"
                  translate-attr-title="nui.facets.showmore">
            </span>

    </md-button>

</div>
<!--show more end-->



<div ng-init="messageAdded = 'open' ; 
          messageRemoved = 'close' "
          class="accessible-only"
          aria-label="{{ctrl.isShowMore(ctrl.facetGroup) ? messageAdded :   messageRemoved}}"
          aria-live="assertive" >{{ctrl.isShowMore(ctrl.facetGroup) ? messageAdded : messageRemoved}} </div>