当分隔符和引号同时用于字段时 awk

当分隔符和引号同时用于字段时 awk

我有一个以下格式的文件:

field1|field2|field3
field1|"field2|field2"|field3

请注意,第二行包含双引号。双引号内的字符串属于字段 2。如何使用 awk 提取该字符串?我一直在谷歌搜索没有结果。我也尝试过但没有运气

FS='"| "|^"|"$' '{print $2}'  

答案1

如果您有最新版本,那么gawk您很幸运。有这个FPAT功能,已记录这里

awk 'BEGIN {
 FPAT = "([^|]+)|(\"[^\"]+\")"
}
{
 print "NF = ", NF
 for (i = 1; i <= NF; i++) {
    sub(/"$/, "", $i); sub(/^"/, "", $i);printf("$%d = %s\n", i, $i)
 }
}' file

NF =  3
$1 = field1
$2 = field2
$3 = field3
NF =  3
$1 = field1
$2 = field2|field2
$3 = field3

答案2

这是你得到的东西csv- 如果分隔符是字段的一部分,它会被引用。这突然使得解析它的任务变得更加困难,因为你不能只在 delim 上进行拆分。

幸运的是,如果perl是一个选项,您就有Text::CSV处理这种情况的模块:

#!/usr/bin/env perl
use strict;
use warnings;

use Text::CSV;

my $csv = Text::CSV -> new ( { 'sep_char' => '|' } );

while ( my $row =  $csv -> getline ( *STDIN ) ) {
   print $row -> [1],"\n";
}

如果您愿意,可以将其压缩为内联/可管道 - 类似:

perl -MText::CSV -e 'print map { $_ -> [1] ."\n" } @{ Text::CSV -> new ( { 'sep_char' => '|' } ) -> getline_all ( *ARGV )};

答案3

您可能需要格式化这些数据,sed以便更容易地解析它awk。例如:

$ sed 's/"//g' awktest1.txt 
field1|field2|field3
field1|field2|field2|field3

$ sed 's/"//g' awktest1.txt > awktest2.txt

$ awk 'BEGIN {FS = "|"} ; {print $2}' awktest2.txt 
field2
field2

但话又说回来,我不知道您正在使用的数据的性质。

相关内容