두 필드 모두에 구분 기호와 따옴표를 사용하는 경우 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. 구분 기호가 필드의 일부인 경우 인용됩니다. 분리로 분할할 수 없기 때문에 갑자기 구문 분석 작업이 훨씬 더 어려워집니다.

다행히도 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

하지만 다시 말하지만, 나는 당신이 작업하고 있는 데이터의 성격을 모릅니다.

관련 정보