根据字段数添加其他字段

Ana*_*hay 6 awk sed

我在文件中有以下格式的数据

"123","XYZ","M","N","P,Q"
"345",
"987","MNO","A,B,C"
Run Code Online (Sandbox Code Playgroud)

我总是希望在行中有 5 个条目,因此如果需要添加 2 中的字段数,则需要添加 3 个额外的 ("")。

"123","XYZ","M","N","P,Q" 
"345","","","",""  
"987","MNO","A,B,C","",""  
Run Code Online (Sandbox Code Playgroud)

我查看了页面上的解决方案

根据字段数添加额外的字符串 - Sed/Awk

它有非常相似的要求,但是当我尝试时它失败了,因为我在字段中也有逗号 (,)。

谢谢。

Rav*_*h13 8

awk带有您显示的示例的GNU中,请尝试以下代码。

awk -v s1="\"" -v FPAT='[^,]*|"[^"]+"' '
BEGIN{ OFS="," }
FNR==NR{
  nof=(NF>nof?NF:nof)
  next
}
NF<nof{
  val=""
  i=($0~/,$/?NF:NF+1)
  for(;i<=nof;i++){
    val=(val?val OFS:"")s1 s1
  }
  sub(/,$/,"")
  $0=$0 OFS val
}
1
'  Input_file  Input_file
Run Code Online (Sandbox Code Playgroud)

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

awk -v s1="\"" -v FPAT='[^,]*|"[^"]+"' ' ##Starting awk program from here setting FPAT to csv file parsing here.
BEGIN{ OFS="," }                         ##Starting BEGIN section of this program setting OFS to comma here.
FNR==NR{                                 ##Checking condition FNR==NR here, which will be true for first time file reading.
  nof=(NF>nof?NF:nof)                    ##Create nof to get highest NF value here.
  next                                   ##next will skip all further statements from here.
}
NF<nof{                                  ##checking if NF is lesser than nof then do following.
  val=""                                 ##Nullify val here.
  i=($0~/,$/?NF:NF+1)                    ##Setting value of i as per condition here.
  for(;i<=nof;i++){                      ##Running loop till value of nof matches i here.
    val=(val?val OFS:"")s1 s1            ##Creating val which has value of "" in it.
  }
  sub(/,$/,"")                           ##Removing ending , here.
  $0=$0 OFS val                          ##Concatinate val here.
}
1                                        ##Printing current line here.
'  Input_file  Input_file                ##Mentioning Input_file names here.
Run Code Online (Sandbox Code Playgroud)

编辑:在此处添加此代码,其中保留一个名为的变量nof,我们可以在其中给出我们应该在所有缺失行中添加的最小字段值的数量,如果任何行的字段值超过最小字段值,则将使用该值添加缺少字段行中的许多字段。

awk -v s1="\"" -v nof="5" -v FPAT='[^,]*|"[^"]+"' '
BEGIN{ OFS="," }
FNR==NR{
  nof=(NF>nof?NF:nof)
  next
}
NF<nof{
  val=""
  i=($0~/,$/?NF:NF+1)
  for(;i<=nof;i++){
    val=(val?val OFS:"")s1 s1
  }
  sub(/,$/,"")
  $0=$0 OFS val
}
1
'  Input_file  Input_file
Run Code Online (Sandbox Code Playgroud)

  • 它有效..谢谢..为什么有输入文件的条目? (2认同)
  • 谢谢您的详细解释。 (2认同)

Jam*_*own 6

这是 GNU awkFPAT[你] 总是希望在行中有 5 个条目时使用的一个:

$ awk '
BEGIN {
    FPAT="([^,]*)|(\"[^\"]+\")"
    OFS=","
}
{
NF=5                              # set NF to limit too long records
for(i=1;i<=NF;i++)                # iterate to NF and set empties to ""
    if($i=="")
        $i="\"\""
}1' file
Run Code Online (Sandbox Code Playgroud)

输出:

"123","XYZ","M","N","P,Q"
"345","","","",""
"987","MNO","A,B,C","",""
Run Code Online (Sandbox Code Playgroud)

  • 因为无论如何你都需要循环,所以在这种情况下首先执行“NF=5”实际上并没有为你做任何事情,除了为执行添加更多的工作/时间。只需去掉“NF=5”并创建循环“for(i=1;i&lt;=5;i++)”,它就会产生相同的输出,但运行速度更快一些。 (3认同)
  • 谢谢..这个解决方案也有效.. (2认同)
  • 我没有考虑到可能有超过5个字段。我想知道在这种情况下所需的行为是否真的是删除数据,或者我们是否应该将空字段添加到现有的数量 - 我认为它会是后者,因为 @RavinderSingh13 正在做,但我不知道。如果少于 5 个,`NF=5` 会添加字段,但如果多于 5 个,它会做什么是未定义的行为,尽管您已经在使用 FPAT 并且它会在 gawk 中执行您想要的操作。 (2认同)

anu*_*ava 6

这是一个awk适用于任何版本的命令awk

awk -v n=5 -v ef=',""' -F '","' '
{
   sub(/,+$/, "")
   for (i=NF; i<n; ++i)
      $0 = $0 ef
} 1' file

"123","XYZ","M","N","P,Q"
"345","","","",""
"987","MNO","A,B,C","",""
Run Code Online (Sandbox Code Playgroud)