我有一个以下格式的文件:
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
但话又说回来,我不知道您正在使用的数据的性质。