악센트 문자가 있는 쉼표로 구분된 텍스트에서 필드 제거

악센트 문자가 있는 쉼표로 구분된 텍스트에서 필드 제거

다음과 같은 CSV 파일이 있습니다.

name;address;phone;email
John;123 La Sierra;555-121212;[email protected]
Nick;456 La Bongaa;555-121232;[email protected]
Carl;789 La Fountain;553-121212;[email protected]

마지막 항목을 제거하고 다음과 같이 만들고 싶습니다.

name;address;phone;
John;123 La Sierra;555-121212;
Nick;456 La Bongaa;555-121232;
Carl;789 La Fountain;553-121212;

마지막 필드는 ;그대로 유지되어야 하지만 마지막 필드는 제거됩니다.

내 질문 중 하나에서 이 코드를 발견하여 이 상황에 맞게 조정했습니다.

perl -000ne '@f=split(/;/); print join(";",@f[0..2]) , "\n"' myFile.csv

분할한 다음 필드 0, 1, 2만 연결하면 된다고 생각했는데 ;작동하지 않습니다.

file명령으로 인해 이 결과가 나왔습니다.myFile.csv

UTF-8 Unicode text, with CRLF line terminators

파일에는 이 작업을 방해할 수 있는 악센트 문자가 포함되어 있습니다.

어떤 아이디어가 있나요?

답변1

코드가 그렇게 많이 필요한지 잘 모르겠으므로 perl비슷한 코드가 있습니다 awk.

awk -F';' -v OFS=';' '{ $NF=""; print }' data.csv

=> 이 코드는 각 행의 마지막 필드( )를 지웁니다 $NF="". 입력 필드( -F\;)와 출력 필드( OFS=';')는 ";"으로 구분됩니다.

다음과 동일 sed:

sed 's/[^;]*$//' data.csv

=> 이는 s/.../.../";"( )이 아닌 가장 긴 문자 시퀀스를 ( ) [^;]*줄 끝에 $아무것도 없는 것으로 대체합니다( ).

다음과 동일 grep:

grep -o '.*;' data.csv

=> grep정규식은 기본적으로 탐욕적입니다. 즉, 가능한 가장 긴 시퀀스와 일치합니다. 따라서 여기서 의미하는 것은 .*;"";"으로 끝나는 가장 긴 문자 시퀀스입니다. 이 -o옵션은 전체 줄 대신 일치하는 내용을 출력합니다.

마지막으로 perl이에 상응하는 내용은 다음과 같습니다(@steeldriver에게 감사드립니다).

perl -F';' -lpe '$F[-1]=""; $_ = join ";", @F' data.csv

=> 와 유사하게 작동하며 awk여기서 연결이 명확합니다.

답변2

방법 bash및 용도shell parameter expansion:

"${line%;*};"

답변3

자르고 싶지 않아? :(

CSV 파일을 사용하고 싶다면,자르다확실히 친구가 될 것입니다:

cut -f 1-3 -d';' semico.csv | xargs -I{} echo {}";"

분해: ';'으로 구분된 열 1~3을 잘라내고(추출한 다음) 각 행에 대해 (cut은 마지막 ';'을 제거하므로 xargs에 전달하고 echo line + ;

확실히 grep보다 느리지만 장기적으로는 작업에 적합한 도구를 사용하는 것이 더 좋습니다.

사람들이 xargs에 만족하지 않기 때문에 대안: cut -f 1-3 -d';' semico.csv | sed 's/$/;/'

같은 일이지만 sed에서는 줄 끝을 ;

관련 정보