【问题标题】:How to add a header to awk output?如何在 awk 输出中添加标头?
【发布时间】:2021-02-16 07:11:47
【问题描述】:

我有一个如下所示的 csv 文件

"10.8.70.67","wireless",,"UTY_07_ISD",,26579
"10.8.70.69","wireless",,"RGB_34_FTR",,19780

我想检索第一、第二和第四列值(不带引号)并以以下格式填充到另一个 csv 中。

IP          DEVICETYPE  DEVICENAME
10.8.70.67  wireless    UTY_07_ISD
10.8.70.69  wireless    RGB_34_FTR

我使用了下面的 awk 命令

awk -F ',|,,' '{gsub(/"/,"",$1); gsub(/"/,"",$2); gsub(/"/,"",$3); print $1, $2, $3}' file.csv

得到下面的输出

10.8.70.67  wireless    UTY_07_ISD
10.8.70.69  wireless    RGB_34_FTR

请帮助为每一列分配标题。

【问题讨论】:

  • @tink,恕我直言,这看起来不像是这个问题的骗子。
  • 您想要的输出根本不是 CSV。请澄清;你真的想要 CSV 的答案(在这种情况下重复是正确的)还是固定宽度的空格分隔列?
  • Hi, I am able to get the required output. I just want to add heading to each column. OP 在我的答案部分给出了这个评论,我认为 OP 可能不需要输出中的 csv 文件,但让我们等待 OP 回到这里,尽管我仍然会说现在做这个欺骗还为时过早,一旦 OP 确认了这一点并且欺骗链接对他来说工作正常,那么它肯定是一个欺骗。
  • 我已经重新打开了这个问题,通过在答案部分Hi, I am able to get the required output. I just want to add heading to each column.(看起来不像是正确的欺骗)上看到 OP 的 cmets,如果 OP 确认三人组的上述 cmets 然后将投票让它欺骗,谢谢。
  • @tink,你好,tink,我可以从历史中看到stackoverflow.com/questions/37216107/…这个链接,这与你现在分享的完全不同。所以我检查了这个链接。此外,OP 解决此问题的方法在这里看起来并不好,因此此处给出的方法将有助于使该部分高效,同时仅添加标题恕我直言。

标签: linux awk


【解决方案1】:

假设你在引用的字符串中没有逗号或双引号(一个很大的假设!)它可以很简单

$ awk -F, 'NR==1 {print "IP","DEVICETYPE","DEVICENAME"} 
                 {gsub(/"/,""); 
                  print $1,$2,$4}' file | column -t

IP          DEVICETYPE  DEVICENAME
10.8.70.67  wireless    UTY_07_ISD
10.8.70.69  wireless    RGB_34_FTR

【讨论】:

  • 我使用命令 awk -F ',|,,' 'BEGIN {print "IP,DEVICETYPE,DEVICENAME"} {gsub(/"/, "", $1); gsub (/"/, "", $2); gsub(/"/, "", $3); print $1","$2","$3}' input.csv > output.csv 我发现我缺少 BEGIN 部​​分。感谢您的回复。
  • @selvanvenkatesh 请注意,即使输入文件为空,BEGIN 也会打印标题。如果输入文件中至少有一行,另一种选择只会添加标题。
【解决方案2】:

对于您显示的示例,您能否尝试以下操作。用 GNU awk 编写和测试。

awk -v FPAT='([^,]*)|("[^"]+")' '
BEGIN{
  OFS=","
  print "IP          DEVICETYPE  DEVICENAME"
}
function remove(fields){
  num=split(fields,arr,",")
  for(i=1;i<=num;i++){
    gsub(/^"|"$/,"",$arr[i])
  }
}
{
  remove("1,2,4")
  print $1,$2,$4
}
' Input_file

说明:为上述添加详细说明。

awk -v FPAT='([^,]*)|("[^"]+")' '    ##Setting FPAT to get only matched fields only as ([^,]*)|("[^"]+") as per samples.
BEGIN{                               ##Starting BEGIN section of this program from here.
  print "IP          DEVICETYPE  DEVICENAME" ##printing header here.
}
function remove(fields){             ##Creating function named remove here where we are passing field numbers from where we need to remove "
  num=split(fields,arr,",")          ##Splitting fields into arr here.
  for(i=1;i<=num;i++){               ##Traversing through all items of arr here.
    gsub(/^"|"$/,"",$arr[i])         ##Globally substituting starting and ending " in mentioned fields with NULL here.
  }
}
{
  remove("1,2,4")                    ##Calling remove here with field numbers of 1,2 and 4 which we need as per output.
  print $1,$2,$4                     ##Printing 1st, 2nd and 4th field here.
}
' Input_file                         ##Mentioning Input_file name here.

【讨论】:

  • 嗨,我能够得到所需的输出。我只想为每一列添加标题。
  • @selvanvenkatesh,当然,我现在已经编辑了我的代码,请检查一下,让我知道它是怎么回事?干杯。
  • @selvanvenkatesh,你也可以看到这个链接What one could do when someone gets helpful answer on SO欢呼,快乐学习。
  • @selvanvenkatesh,您能否在问题部分回复 Tripleee 的评论(在该部分中询问您是否需要 csv 文件)并确认附加的重复问题链接是否对您有帮助,谢谢。
  • 我使用命令 awk -F ',|,,' 'BEGIN {print "IP,DEVICETYPE,DEVICENAME"} {gsub(/"/, "", $1); gsub (/"/, "", $2); gsub(/"/, "", $3); print $1","$2","$3}' input.csv > output.csv 我发现我缺少 BEGIN 部​​分。感谢 Ravinder 的回复。
【解决方案3】:

一个简单的oneliner将是:

awk -F ',|,,' 'BEGIN {format = "%-20s %-20s %-20s\n"; printf format, "IP", "DEVICETYPE", "DEVICENAME"} {gsub(/"/,"",$1); gsub(/"/,"",$2); gsub(/"/,"",$3); printf format, $1, $2, $3}' abc.csv

这里我使用了 BEGIN/END 特殊模式,用于执行一些启动或清理操作,以添加标题。更多详情请参考文档Using BEGIN/END

【讨论】:

  • 我使用命令 awk -F ',|,,' 'BEGIN {print "IP,DEVICETYPE,DEVICENAME"} {gsub(/"/, "", $1); gsub (/"/, "", $2); gsub(/"/, "", $3); print $1","$2","$3}' input.csv > output.csv 我发现我缺少 BEGIN 部​​分。感谢您的回复。
【解决方案4】:

我通过以下命令得到了预期的输出

awk -F ',|,,' 'BEGIN {print "IP,DEVICETYPE,DEVICENAME"} {gsub(/"/, "", $1); gsub(/"/, "", $2); gsub(/"/, "", $3); 打印 $1","$2","$3}' input.csv > output.csv

我发现我缺少 BEGIN 部​​分。谢谢大家的回复。

【讨论】:

    猜你喜欢
    • 2020-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-05
    • 2019-02-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多