【问题标题】:changing content of the column without destroying formating在不破坏格式的情况下更改列的内容
【发布时间】:2011-03-11 04:16:10
【问题描述】:

$ echo "a b" | awk '{打印 $0; $1="1";打印 $0}' 一个 1个

我想收到这样的格式化输出:

 a       b
 1       b

有没有简单的方法来做到这一点(没有 IFS、OFS 更改)? 我正在更改大表中的列,然后看起来很难看。 我不想重新格式化每一列。

谢谢。

【问题讨论】:

    标签: awk gawk


    【解决方案1】:

    您最好的选择可能是对输出进行后处理。也许像这样简单:

    $ ... |啊... |列-t

    会起作用。 (除非“我不想格式化每一列”的意思是“我不想重新格式化每一行”,例如“我不想发布流程”。在这种情况下,我会问,“为什么不呢? ")

    【讨论】:

      【解决方案2】:

      一个可能的答案(假设列数固定):

      echo "a       b" | awk '{print $0; $1="1"; printf("%s\t%s\n", $1, $2)}'
      

      另一个可能的答案(假设您没有充分的理由避免更改 OFS,因为您知道,这就是拥有一个的全部意义!):

      echo "a       b" | awk 'BEGIN { OFS="\t" } {print $0; $1="1"; print $0}'
      

      第二个的优点是不管你的文本文件有多少列都可以工作。


      编辑添加:

      为了解释为什么我认为您对使用 OFS 的反感很奇怪,只是您获得格式更改的全部原因是因为 OFS。默认情况下,输出字段分隔符 (OFS) 是一个空格。当您第一次打印 $0 时,您没有进行任何修改,因此 $0 是未更改的行。通过更改您在 Awk 中创建的记录之一,通过从各个字段重新组合 $0 来重新评估该行。当然,重新组装后,Awk 在字段之间插入了 OFS。因为那是它应该做的。引用相关手册页(man gawk):

      当引用$0 时,将值分配给现有字段会导致重建整个记录。 同样,为$0 赋值会导致记录被重新拆分,从而为字段创建新值。

      现在我同意第一次打印和第二次以不同方式处理字段之间存在一些不一致,但这正是语言的方式。在您实际更改字符串并实际计算字段并重新构建等之前,不会插入 OFS。


      进一步编辑添加:

      观看这些:

      $ awk 'BEGIN { printf("|%s|\n", OFS) }'
      | |
      $ awk 'BEGIN { OFS="\t" ; printf("|%s|\n", OFS) }'
      |   |
      $ 
      

      在您的第一个示例中,Awk 的行为是否变得更加清晰,以及为什么您实际上需要 OFS 或 printf 等?

      【讨论】:

      • 感谢您的回答。它确实为问题带来了理解。
      【解决方案3】:

      你也可以使用替换

      $ echo "a       b" | awk '{print $0; gsub("^[^ \t]","1"); print $0}'
      a       b
      1       b
      

      【讨论】:

      • 这就是我一开始所做的,但“| column -t”是更好的方式。我可以更改我想要的任何列,最后仍然有漂亮的格式化表格。
      猜你喜欢
      • 1970-01-01
      • 2021-03-14
      • 2010-12-21
      • 1970-01-01
      • 1970-01-01
      • 2016-10-29
      • 2019-02-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多