AWK 명령 - CSV의 빈 "셀"을 텍스트 값으로 편집합니다.

AWK 명령 - CSV의 빈 "셀"을 텍스트 값으로 편집합니다.

내 문제가 인쇄상의 오류에 더 가깝다면 죄송합니다. 하지만 한동안 이 문제를 해결하려고 노력했지만 안타깝게도 제대로 작동하도록 할 수 없습니다. sed 명령을 사용해야 할 수도 있지만 sed에서 열을 지정하는 방법을 파악하지 못했고 초보자이지만 awk 명령에 대한 경험이 더 많습니다.

이것이 목표입니다. 일부 행에는 null(공백) 값이 있고 다른 행에는 값이 있는 열(14)이 있는 CSV 파일 file1이 있습니다. 여전히 다른 모든 열을 출력에 포함하고 싶지만 14열의 빈(null) 열을 새 값으로 변경하면 됩니다.해당 없음.

예:

열 14
값 1
값 2

값 3

awk 명령을 사용하여 열 14에서 빈 행을 찾고, 발견되면 셀에 새 텍스트 값 NA를 입력했습니다.

이것이 제가 시도하고 있는 명령이지만 새 파일의 14열에 여전히 빈 셀이 있습니다. 어떤 도움이라도 대단히 감사하겠습니다. 감사해요.

주문하다:

awk -F"," 'BEGIN {OFS=","} $14 == "" { $14 = "NA" }  {print}' file1 > file2


표적:

예:

열 14
값 1

2 해당 없음
값 3

시간을 내어 읽고 도움을 주신 모든 분들께 감사드립니다.

고쳐 쓰다

요청에 따라 다음은 몇 가지 샘플 데이터입니다.

"employee_number","employee_login","is_active","send_pkg_email","send_na_email","last_name","first_name","department","title","phone_number","employee_type","email","charge_code","area_code","mailstop","roomid"
"103293","[email protected]","Y","","","Smith","Jessica","","","+1 (650) 3530975","Employee","[email protected]","","LOC0028.03","","03.C.01H"
"103295","[email protected]","Y","","","Long","Fred","","","+1 (415) 9449428","Employee","[email protected]","","LOC0025.01","","01.D.04B"
"103297","[email protected]","Y","","","Cheng","Laura","","","+1 (650) 8623342","Contingent","[email protected]","","","",""
"103307","[email protected]","Y","","","Brown","Chris","","","+1 (512) 9644927","Employee","[email protected]","","ATX0607.16","","16.B.10D"
"103310","[email protected]","Y","","","Williams","Stan","","","+1 (650) 8048591","Employee","[email protected]","","LOC0061.03","","03.D.01B"

답변1

$ perl -MText::CSV=csv -e '
  $csv = Text::CSV->new();
  while(my $row = $csv->getline(ARGV)) {
    $row->[13] = "NA" if ($row->[13] eq "");
    $csv->say(STDOUT, $row);
  };' input.csv

Perl 배열은 1이 아닌 0에서 시작하므로 필드 14는 $rowarrrayref의 요소 13입니다.

employee_number,employee_login,is_active,send_pkg_email,send_na_email,last_name,first_name,department,title,phone_number,employee_type,email,charge_code,area_code,mailstop,roomid
103293,[email protected],Y,,,Smith,Jessica,,,"+1 (650) 3530975",Employee,[email protected],,LOC0028.03,,03.C.01H
103295,[email protected],Y,,,Long,Fred,,,"+1 (415) 9449428",Employee,[email protected],,LOC0025.01,,01.D.04B
103297,[email protected],Y,,,Cheng,Laura,,,"+1 (650) 8623342",Contingent,[email protected],,NA,,
103307,[email protected],Y,,,Brown,Chris,,,"+1 (512) 9644927",Employee,[email protected],,ATX0607.16,,16.B.10D
103310,[email protected],Y,,,Williams,Stan,,,"+1 (650) 8048591",Employee,[email protected],,LOC0061.03,,03.D.01B

Employee_number를 포함하는 행은 103297이제해당 없음14번째 게임에서.

그런데 여기의 출력 필드는 필요한 경우에만 큰따옴표로 묶입니다(예: 공백이 포함된 경우. 또는 쉼표가 포함된 경우에도 따옴표로 묶임). 출력의 모든 필드를 입력 파일에서와 같이 참조하려면 이 $csv = Text::CSV->new();줄을 다음으로 변경합니다.

$csv = Text::CSV->new({always_quote => 1});

텍스트::CSV다른 많은 옵션이 있습니다. 예를 들어 이를 사용하면 $csv = Text::CSV->new({always_quote => 1, strict => 1});입력 행의 필드 수가 다른 경우에도 오류가 발생합니다. man Text::CSV자세히보다.


또는 awk 스크립트에 대한 간단한 수정:

awk -F"," 'BEGIN {OFS=","}; $14 == "\"\"" { $14 = "\"NA\"" };1' input.csv

이는 CSV 파일을 분할하는 데에만 쉼표를 사용할 때 발생하는 문제를 강조합니다. "필드 데이터로 래핑된 문자와 "필드 데이터의 일부인 문자를 구별하는 것은 불가능합니다 . 이 간단한 분할 방법은 그러한 구별을 하지 않기 때문입니다.

필드 14아니요입력 줄을 쉼표로 구분하는 경우에는 비어 있습니다. 두 개의 따옴표 문자( "")가 포함되어 있습니다.

이 awk 한 줄 문은 필드에 쉼표 문자가 포함된 경우에도 중단됩니다. 이것이 CSV 파서를 사용하는 것이 더 나은 또 다른 이유입니다.

바라보다csv 파일을 처리하는 강력한 명령줄 도구가 있습니까?.

좋은 awk csv 파서도 있습니다https://github.com/geoffroy-aubry/awk-csv-parser

답변2

그러나 열 14에는 빈 문자열이 포함되어 있지 않으므로 ""두 따옴표(이스케이프해야 함)를 모두 확인해야 합니다.

awk -F"," 'BEGIN {OFS=","} $14 == "\"\"" { $14 = "NA" } {print}' file1 > file2

관련 정보