如何在Unix中使用awk从文本文件中打印奇数字段?

时间:2014-11-11 06:12:53

标签: unix awk printf

我之前发过同样的问题,但由于我只是Unix中的初学者,我无法理解给出的答案,但肯定有助于满足我的要求。

awk -F\| '{s="";for (i=1;i<=NF;i+=2) {s=s?s FS $i:$i} print s}' file

这个{s = s?s FS $ i:$ i}打印s}做什么?它如何打印所需的输出?我无法理解。是不是在Unix中使用print或printf语句进行打印的特殊操作符? 请解释 。任何帮助将非常感激。感谢。

3 个答案:

答案 0 :(得分:3)

? :是awk提供的三元运算符

<强>语法

expression ? value 1 : value 2

如果表达式的计算结果为true,那么三元表达式的值为value1 else value2

例如假设var =1

output=var==1 ? 10 : 5;

此处var==1评估为真,三元运算符的值为10,因此output变为10

现在 {s=s?s FS $i:$i} print s}做什么

    {li>

    s ?s不为空时评估为真。那是它没有处理第一个列。它设置的s FS $i sFS分隔$i分隔s==""

  • 评估为false时,s$i设置为第一列|

这可以确保fiels seprator $ cat input one|two|three|four|five|six $ awk -F\| '{s="";for (i=1;i<=NF;i+=2) { {s=s?s FS $i:$i} print s }}' input 仅在第一列以外的每一列之前添加

进一步了解文件

print s

这里for适用于给出输出的one <= s="", evaluates false, hence no FS, | added to column one|three <= s=one, evaluates true, hence FS, | added to column and so on one|three|five 循环的每次迭代

{{1}}

答案 1 :(得分:1)

如果我们重新格式化您的awk代码可能会更清楚:

{
  s = "";
  for (i = 1; i <= NF; i += 2)
  {
    s = s ? s FS $i : $i
  }
  print s
}

首先,我们对从1到NF的所有奇数进行循环。在其中,我们构建了一个字符串s。每次循环迭代,如果s不为空,我们追加FS $i;如果它是空的,我们只需指定$i。所有这一切的净效果是使s包含来自所有奇数字段的文本,以FS分隔。最后,我们打印s

更简洁的形式,没有三元,将是:

{
  s = $1;
  for (i = 3; i <= NF; i += 2)
  {
    s = s FS $i
  }
  print s
}

答案 2 :(得分:1)

awk -F\| '{s="";for (i=1;i<=NF;i+=2) {s=s?s FS $i:$i} print s}' file

1)-F \ | =&GT; field seperator设置为| (逃避要求,因此\ |)

2)s =“”=&gt;一个空字符串

3)for(i = 1; i <= NF; i + = 2)=&gt; NF表示正在处理的当前记录中的字段数。对于从第1个字段到最后字段的循环,跳过奇数字段(不是i + = 2)

4)s = s?s FS $ i:$ i =&gt; 这将检查s是否等于s.if yes,然后它将第i个字段附加到s(s FS $ i)。如果不是,那么它会将ith字段复制到s($ i)。这不是真正需要的,它可以是s = s FS $ i