【问题标题】:Append delimiters for implied blank fields为隐含的空白字段附加分隔符
【发布时间】:2020-02-21 08:07:56
【问题描述】:

我正在寻找一种简单的解决方案,让文件(CSV 文件)中的每一行都有相同数量的逗号

例如

文件示例:

1,1
A,B,C,D,E,F
2,2,
3,3,3,
4,4,4,4

预期:

1,1,,,,
A,B,C,D,E,F
2,2,,,,
3,3,3,,,
4,4,4,4,,

在这种情况下,逗号数量最多的行有 5 个逗号(第 2 行)。所以,我想在所有行中添加其他逗号以使每行具有相同的数字(即 5 个逗号)

【问题讨论】:

    标签: shell awk delimiter


    【解决方案1】:

    使用 awk:

    $ awk 'BEGIN{FS=OFS=","} {$6=$6} 1' file
    1,1,,,,
    A,B,C,D,E,F
    2,2,,,,
    3,3,3,,,
    4,4,4,4,,
    

    正如您在上面看到的,在这种方法中,最大值。必须在命令中硬编码字段数。

    【讨论】:

      【解决方案2】:

      另一种方法是让 CSV 文件中的所有行都具有相同数量的字段。字段的数量不需要知道。将计算 max 字段并将所需逗号的子字符串附加到每条记录,例如

      awk -F, -v max=0 '{
          lines[n++] = $0             # store lines indexed by line number
          fields[lines[n-1]] = NF     # store number of field indexed by $0
          if (NF > max)               # find max NF value
              max = NF
      }
      END {
          for(i=0;i<max;i++)          # form string with max commas
              commastr=commastr","
          for(i=0;i<n;i++)            # loop appended substring of commas 
              printf "%s%s\n", lines[i], substr(commastr,1,max-fields[lines[i]])
      }' file
      

      使用/输出示例

      在命令行粘贴,您将收到:

      $ awk -F, -v max=0 '{
      >     lines[n++] = $0             # store lines indexed by line number
      >     fields[lines[n-1]] = NF     # store number of field indexed by $0
      >     if (NF > max)               # find max NF value
      >         max = NF
      > }
      > END {
      >     for(i=0;i<max;i++)          # form string with max commas
      >         commastr=commastr","
      >     for(i=0;i<n;i++)            # loop appended substring of commas
      >         printf "%s%s\n", lines[i], substr(commastr,1,max-fields[lines[i]])
      > }' file
      1,1,,,,
      A,B,C,D,E,F
      2,2,,,,
      3,3,3,,,
      4,4,4,4,,
      

      【讨论】:

        【解决方案3】:

        请您尝试以下更通用的方式。此代码将起作用,即使您的 Input_file 中的字段数不相同,并且将首先从整个文件中读取并获取最大字段数,然后第二次读取文件它将重置字段(为什么因为我们将 OFS 设置为,所以如果当前行的字段数小于 nf 值,许多逗号将添加到该行)。 @oguz ismail 答案的增强版。

        awk '
        BEGIN{
         FS=OFS=","
        }
        FNR==NR{
         nf=nf>NF?nf:NF
         next
        }
        {
         $nf=$nf
        }
        1
        '  Input_file  Input_file
        

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

        awk '                ##Starting awk program frmo here.
        BEGIN{               ##Starting BEGIN section of awk program from here.
         FS=OFS=","          ##Setting FS and OFS as comma for all lines here.
        }
        FNR==NR{             ##Checking condition FNR==NR which will be TRUE when first time Input_file is being read.
         nf=nf>NF?nf:NF      ##Creating variable nf whose value is getting set as per condition, if nf is greater than NF then set it as NF else keep it as it is,
         next                ##next will skip all further statements from here.
        }
        {
         $nf=$nf             ##Mentioning $nf=$nf will reset current lines value and will add comma(s) at last of line if NF is lesser than nf.
        }
        1                    ##1 will print edited/non-edited lines here.
        ' Input_file Input_file      ##Mentioning Input_file names here.
        

        【讨论】:

        • @DavidC.Rankin,实际上我正在运行带有 2 个 Input_file 的代码。第一个扫描并获得最大数量的字段值,第二个只是简单地做$nf=$nf 它的oguzismail 认为我让它更通用:) 当我们做$nf=$nf 然后它重新创建该行并添加, 如果当前行字段数小于最大值,如有任何疑问,请随时咨询,老实说,你在 awk 方面比我好 :)
        • 我明白了——这也是一种巧妙的方法!我看到了这两个输入文件,但没有注意到这只是一种简单的方法,可以通过同一文件运行两次,在第一次通过时收集最大值:)
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-04-01
        • 2010-09-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多