파일의 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.