【问题标题】:Chop a row into multiple rows using awk使用 awk 将一行切成多行
【发布时间】:2016-08-05 18:33:14
【问题描述】:

我正在尝试使用 awk 将一行分成多行。每两个字之后。

输入:

hey there this is a test 

输出:

hey there
this is
a test

我可以使用 xargs 来实现它,如下所示:

echo hey there this is a test |xargs -n2
hey there
this is
a test

但是我很想知道如何使用 awk 来实现这一点。这是我正在使用的命令,当然没有给出预期的结果。

echo hey there this is a test | awk '{ for(i=1;i<=NF;i++) if(i%2=="0") ORS="\n" ;else ORS=" "}1'
hey there this is a test

echo hey there this is a test | awk '{$1=$1; for(i=1;i<=NF;i++) if(i%2==0) ORS="\n" ;else ORS=" "}{ print $0}'
hey there this is a test

需要了解上述 awk 命令在概念上的错误以及如何修改它以提供正确的输出。假设输入是单行的。

感谢和问候。

【问题讨论】:

    标签: bash awk


    【解决方案1】:

    使用 awk 你可以做到:

    s='hey there this is a test'
    awk '{for (i=1; i<=NF; i++) printf "%s%s", $i, (i%2 ? OFS : ORS)}' <<< "$s"
    
    hey there
    this is
    a test
    

    【讨论】:

    • ++太棒了,它奏效了。明白我在做什么错误。谢谢。
    【解决方案2】:

    首先,您需要 OFS(字段分隔符)而不是 ORS(记录分隔符)。 而你的 for 最终设置了一个 ORS,它遍历所有字段并在 " " 和 "\n" 之间来回设置 ORS 值,最后只有一个值。

    所以你真正想要的是对记录(通常是行)而不是字段(通常是空格分隔它们)进行操作。

    这是一个使用记录的版本:

    echo hey there this is a test | awk 'BEGIN {RS=" "} {if ((NR-1)%2 == 0) { ORS=" "} else {ORS="\n"}}1' 
    

    结果:

    hey there
    this is
    a test
    

    【讨论】:

      【解决方案3】:

      @krzyk 版本的另一种风格:

      $ awk 'BEGIN {RS=" "} {ORS="\n"} NR%2 {ORS=" "} 1' test.in
      hey there
      this is
      a test
      
      $
      

      甚至可能:

      awk 'BEGIN {RS=" "} {ORS=(ORS==RS?"\n":RS)} 1' test.in
      

      不过,他们最后都留下了一个丑陋的入口。

      【讨论】:

        猜你喜欢
        • 2015-11-07
        • 2020-01-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-07-06
        • 1970-01-01
        • 2023-01-12
        相关资源
        最近更新 更多