web-dev-qa-db-ja.com

フィールドに区切り文字と引用符の両方が使用されている場合はawk

次の形式のファイルがあります。

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

2行目には二重引用符が含まれていることに注意してください。二重引用符内の文字列はフィールド2に属しています。awkを使用してこれをどのように抽出しますか?結果は出ませんでした。私も運が悪いのでこれを試しました

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

gawkの最新バージョンを使用している場合は、運がいいです。文書化されたFPAT機能があります here

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
9
iruvar

これはcsvで取得できるものです。区切り文字がフィールドの一部である場合は、引用符で囲まれます。デリムで分割することはできないので、それは突然それを解析するタスクを非常に難しくします。

幸い、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 )};
1
Sobrique