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

时间:2018-09-18 11:05:46

标签: linux bash awk

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

输入:

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 个答案:

答案 0 :(得分:3)

使用gawk:

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,{ {1}},依此类推。

     

$3:输出字段分隔符

答案 1 :(得分:2)

除了最后两个字段外,在字段之间有两个空格作为分隔符。因此,您可以将FS设置为" "进行匹配,并将OFS设置为" | ",以便在输出时进行转换。您只需要对最后一个字段进行特殊处理,将其拆分,然后将其转换为两个字段即可输出。

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

答案 2 :(得分:1)

另一个GNU awk(版本> = 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(字段模式)。

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

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

最后一条语句$1=$1告诉awk根据输出字段分隔符OFS重新构建字符串。

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