代码之家  ›  专栏  ›  技术社区  ›  ashish_k

在特定列之间插入管道作为分隔符的步骤

  •  0
  • ashish_k  · 技术社区  · 7 年前

    我需要将管道作为文件中特定列之间的分隔符。

    输入:

    AQ  92  18-09-2018 00:00:00  29  AR  18-09-2018 05:07:15 18-09-2018 08:06:56
    BG  98  18-09-2018 00:00:00  29  AR  18-09-2018 05:07:15 18-09-2018 08:06:56
    

    预期输出:

    AQ | 92 | 18-09-2018 00:00:00 | 29 | AR | 18-09-2018 05:07:15 | 18-09-2018 08:06:56
    BG | 98 | 18-09-2018 00:00:00 | 29 | AR | 18-09-2018 05:07:15 | 18-09-2018 08:06:56
    

    我试过用下面这样的东西 awk 但不确定如何进一步:

    awk '{gsub(/ /,"|")}1;(NF==3)' file_name
    
    3 回复  |  直到 7 年前
        1
  •  3
  •   Cyrus    7 年前

    呆呆地看着:

    awk 'BEGIN{FIELDWIDTHS="3 4 21 4 4 21 21"; OFS="|"} {print $1,$2,$3,$4,$5,$6," "$7}' file
    

    输出:

    AQ | 92 | 18-09-2018 00:00:00 | 29 | AR | 18-09-2018 05:07:15 | 18-09-2018 08:06:56
    BG | 98 | 18-09-2018 00:00:00 | 29 | AR | 18-09-2018 05:07:15 | 18-09-2018 08:06:56
    

    FIELDWIDTHS 变量包含一个以空格分隔的数字列表,每个字段的宽度都是固定的,gawk使用指定的宽度将记录拆分为 $1 , $2 , $3 等等。

    OFS :输出字段分隔符

        2
  •  2
  •   Barmar    7 年前

    除了最后两个字段外,您还有两个空格作为字段之间的分隔符。所以你可以设定 FS " " 匹配这个,然后设置 OFS " | " 所以它们将在输出时转换。您只需要对最后一个字段做一些特殊的操作,将其拆分,然后将其转换为两个字段进行输出。

    awk -F"  " -v OFS=" | " '{ 
        split($NF, a, " "); 
        $NF = a[1]" "a[2]; 
        $(NF+1) = a[3]" "a[4]; 
        print }'
    
        3
  •  1
  •   oliv    7 年前

    另一个gnu awk(version>=4.0)脚本:

    awk 'BEGIN{FPAT="[A-Z0-9]{2}|([0-9]{2}-?){4} ([0-9]{2}:?){3}"; OFS=" | "}$1=$1' file
    AQ | 92 | 18-09-2018 00:00:00 | 29 | AR | 18-09-2018 05:07:15 | 18-09-2018 08:06:56
    BG | 98 | 18-09-2018 00:00:00 | 29 | AR | 18-09-2018 05:07:15 | 18-09-2018 08:06:56
    

    这依赖于 FPAT (字段模式)指示字段的外观。

    在这种情况下,有两种模式:

    • [A-Z0-9]{2} 匹配2位或字母
    • ([0-9]{2}-?){4} ([0-9]{2}:?){3} 与日期时间字符串匹配

    最后一句话 $1=$1 讲述 awk 根据输出字段分隔符重新构建字符串 OFS .

    此解决方案不依赖字段之间的空间量。