파일의 5 번째 열 값을 기반으로 .CSV 파일을 필터링하고 해당 레코드를 새 파일로 인쇄


16

아래 형식의 .CSV 파일이 있습니다.

"column 1","column 2","column 3","column 4","column 5","column 6","column 7","column 8","column 9","column 10
"12310","42324564756","a simple string with a , comma","string with or, without commas","string 1","USD","12","70%","08/01/2013",""
"23455","12312255564","string, with, multiple, commas","string with or, without commas","string 2","USD","433","70%","07/15/2013",""
"23525","74535243123","string , with commas, and - hypens and: semicolans","string with or, without commas","string 1","CAND","744","70%","05/06/2013",""
"46476","15467534544","lengthy string, with commas, multiple: colans","string with or, without commas","string 2","CAND","388","70%","09/21/2013",""

파일의 5 번째 열에 다른 문자열이 있습니다. 5 번째 열 값을 기준으로 파일을 필터링해야합니다. 다섯 번째 필드에 "string 1"값만있는 레코드가있는 현재 파일의 새 파일이 필요합니다.

이를 위해 아래 명령을 시도했습니다.

awk -F"," ' { if toupper($5) == "STRING 1") PRINT }' file1.csv > file2.csv

하지만 다음과 같이 오류가 발생했습니다.

awk: { if toupper($5) == "STRING 1") PRINT }
awk: ^ syntax error
awk: { if toupper($5) == "STRING 1") PRINT }
awk: ^ syntax error

그런 다음 이상한 출력을 제공하는 다음을 사용했습니다.

awk -F"," '$5="string 1" {print}' file1.csv > file2.csv

산출:

"column 1" "column 2" "column 3" "column 4" string 1 "column 6" "column 7" "column 8" "column 9" "column 10
"12310" "42324564756" "a simple string with a comma" string 1 without commas" "string 1" "USD" "12" "70%" "08/01/2013" ""
"23455" "12312255564" "string with string 1 commas" "string with or without commas" "string 2" "USD" "433" "70%" "07/15/2013" ""
"23525" "74535243123" "string with commas string 1 "string with or without commas" "string 1" "CAND" "744" "70%" "05/06/2013" ""
"46476" "15467534544" "lengthy string with commas string 1 "string with or without commas" "string 2" "CAND" "388" "70%" "09/21/2013" ""

추신 : 문자열이 소문자인지 또는 대문자인지 확실하지 않기 때문에 toupper 명령을 안전한면에 사용했습니다. 코드에 어떤 문제가 있는지, AWK를 사용하여 패턴을 검색하는 동안 문자열의 공백이 중요한지 알아야합니다.

답변:


17
awk -F '","'  'BEGIN {OFS=","} { if (toupper($5) == "STRING 1")  print }' file1.csv > file2.csv 

산출

"12310","42324564756","a simple string with a , comma","string with or, without commas","string 1","USD","12","70%","08/01/2013",""
"23525","74535243123","string , with commas, and - hypens and: semicolans","string with or, without commas","string 1","CAND","744","70%","05/06/2013",""

나는 이것이 당신이 원하는 것이라고 생각합니다.


결과는 내가 필요한 그대로입니다. 난 '","'구분자 로 만드는 생각하지 않았다면 그렇지 않으면 내 문제를 해결했을 것입니다 ... 훌륭한 해결책 ...
Dhruuv

@Dhruuv '","'는 구분 기호를 만드는 것이 이전 질문에 대한 대부분의 답변입니다 :).
terdon

@ terdon : 예, 알고 있지만 문제가있을 때 내 마음에 들지 않았습니다. 솔직히 말해서, 명령이 있거나 문제를 일으킨 구분 기호 이외의 것이 될 수 있다고 생각했습니다 ... :) 따라서 시도하지 않았습니다 ... :(
Dhruuv

2
@Dhruuv는 당신이하려는 일을 말할 수 없기 때문에 세부 사항에 대해 확신하지 못하지만 다른 조건은 거의 확실하지 않습니다. $ 5가 HYPERION 인 경우 ony를 인쇄하려고합니까? 그렇다면을 시도하십시오 else{if(toupper($5)=="HYPERION"){print}}. 내 컴퓨터가 아니므로 구문이 잘못되었을 수 있지만 else 문에 조건을 줄 수는 없습니다.
terdon

1
awk -F '","' 'BEGIN {OFS=","} { if (NR==1) {print} else{if (toupper($5) == "STRING 1") print} }' file1
limovala

2

CSV의 문제점은 표준이 없다는 것입니다. CSV 형식의 데이터를 자주 처리해야하는 경우 ","필드 구분 기호로 사용하는 것이 아니라보다 강력한 방법을 사용하는 것이 좋습니다 . 이 경우 Perl의 Text::CSVCPAN 모듈은 다음 작업에 매우 적합합니다.

$ perl -mText::CSV_XS -WlanE '
    BEGIN {our $csv = Text::CSV_XS->new;} 
    $csv->parse($_); 
    my @fields = $csv->fields(); 
    print if $fields[4] =~ /string 1/i;
' file1.csv
"12310","42324564756","a simple string with a , comma","string with or, without commas","string 1","USD","12","70%","08/01/2013",""
"23525","74535243123","string , with commas, and - hypens and: semicolans","string with or, without commas","string 1","CAND","744","70%","05/06/2013",""

-1
awk 'BEGIN {FS = "," }'  '{ (if toupper($5)  == "STRING 1") print; }'  file1.csv > file2.csv

죄송하지만, 귀하의 솔루션은 파일에서 어떤 레코드도 반환하지 않습니다 ... 그냥 구분 기호를 추가하는 '","'것 같습니다 ... 고마워요 ... :)
Dhruuv

@Mohsen -1 때문에 1) "또는 파일 구분 기호의 일부로 이해되지 않습니다. OP의 다른 질문에 대한 답변을 참조하십시오. 2) BEGIN 블록을 나머지 명령에서 완전히 분리하기 때문입니다. 시도해 awk 'BEGIN {FS = "," }' '{print $0}'보시면 결과가 나오지 않을 것입니다. 나중에 답변을 게시하여 실제로 게시하기 전에 작동하는지 확인하십시오.
terdon
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.