다음과 같은 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에서는 줄 끝을 ;