
학생의 연락처 정보가 포함된 데이터 세트가 있는데, 샘플 데이터 세트는 다음과 같습니다.
First Name, Last Name, Address, Phone Number
John, Doe, "House # 11, Street xyz, Road, Area",00000000
Sara, Taylor, "Jake Lake%, Apartment #22, Main Road, Area XYZ", 00000000
교체하기 위해 다음 명령을 실행하고 있습니다.,주소 열 내부|DB에 로드하려고 합니다.
awk '!(NR%2){gsub(",","|")} {printf RFS $0} {RFS="\""}' RS=\" fileName.txt > output.txt
내가 직면하고 있는 문제는 이 명령을 실행할 때마다 다음 오류가 반환된다는 것입니다. 처음에는 정상적으로 실행 중이었습니다.
awk: run time error: not enough arguments passed to printf(""Jake Lake%, Apartment #22, Main Road, Area XYZ")
그것에 대한 해결책이 있습니까? 난 그것을 알아 챘다%주소로 오는 중인데 그게 문제인가요?
답변1
- 견고성을 위해 절대로 사용하지 마십시오. 입력에 형식 지정 문자가 포함된 경우 전자가 실패하므로
printf $0
항상 대신 사용하십시오 (현재 보고 있는 대로). 모든 입력 데이터를 사용하는 경우에도 동일하게 적용됩니다 .printf "%s", $0
printf
printf
- 명확성과 견고성을 위해 모두 대문자 변수 이름을 사용하지 마십시오. 예를 들어
RFS
내장 변수 이름과의 충돌을 방지하고 내장 변수를 사용하지 않는 것처럼 보이게 하여 코드를 난독화하는 것을 방지합니다. - 가독성을 위해, 예를 들어 다른 입력 파일에 대해 다른 값으로 설정해야 하는 경우를 제외하고는 스크립트 뒤에 변수를 설정하지 마십시오.
RS
스크립트 앞이나 시작 부분에 변수를 설정하여 스크립트를 읽을 때 변수가 설정되기 전에 표시되도록 하십시오. 사용되는 것을 보십시오. - 효율성, 단순성, 견고성을 위해 *sub()의 첫 번째 인수는 문자열이 아닌 정규 표현식이므로 어떤 이유로 정적 정규 표현식 대신 동적이 필요하지 않은 한
/.../
문자열( ) 구분 기호가 아닌 정규 표현식( )을 사용하세요."..."
- 명확성과 유지 관리성을 위해 동일한 값을 가져야 하는 2개의 변수(예:
RS
및RFS
)가 있는 경우 별도로 동일한 값으로 설정하지 마십시오. 예를 들어 두RS="\""; RFS="\""
변수를 해당 값으로 함께 설정하거나RS=RFS="\""
하나를 다른 것으로 설정하십시오.RS="\""; RFS=RS
.
질문에 코드를 올바르게 작성하는 방법은 다음과 같습니다.
$ awk -v RS='"' '!(NR%2){gsub(/,/,"|")} {printf "%s%s", rfs, $0; rfs=RS}' file
First Name, Last Name, Address, Phone Number
John, Doe, "House # 11| Street xyz| Road| Area",00000000
Sara, Taylor, "Jake Lake%| Apartment #22| Main Road| Area XYZ", 00000000
awk를 사용하여 CSV로 그 이상의 작업을 수행하려면 다음을 참조하세요.csv를 사용하여 효율적으로 구문 분석하는 가장 강력한 방법은 무엇입니까?.
답변2
RFS
발생하는 오류는 (빈 변수) 값의 연결을 사용 $0
하고 printf
.
파일은 일부 구분 쉼표 뒤에 공백이 있는 것을 제외하고 유효한 CSV 파일입니다(이로 인해 필드 인용이 엉망이 됩니다 Address
. 인용된 필드에는 구분 기호 바로 뒤에 초기 인용 문자가 있어야 합니다). csvformat
(csvkit의 일부를 사용하여 이를 수정할 수 있습니다 .https://csvkit.readthedocs.io/en/latest/):
$ csvformat --skipinitialspace file.csv >fixed-file.csv
$ cat fixed-file.csv
First Name,Last Name,Address,Phone Number
John,Doe,"House # 11, Street xyz, Road, Area",00000000
Sara,Taylor,"Jake Lake%, Apartment #22, Main Road, Area XYZ",00000000
CSV를 파싱할 수 있는 데이터베이스는 이를 그대로 읽을 수 있어야 합니다.
포함된 모든 쉼표를 로 바꾸시겠습니까? |
파일의 구분 기호를 쉼표가 아닌 다른 것으로 변경하고(아래 탭을 사용하겠습니다) 나머지 쉼표를 모두 파이프로 변경한 다음 다시 쉼표를 구분 기호로 사용하도록 다시 변경하세요.
원본 데이터에 대해 직접 이 작업을 수행할 수 있습니다.
$ csvformat --skipinitialspace --out-tabs file.csv | tr ',' '|' | csvformat --tabs >fixed-file.csv
$ cat fixed-file.csv
First Name,Last Name,Address,Phone Number
John,Doe,House # 11| Street xyz| Road| Area,00000000
Sara,Taylor,Jake Lake%| Apartment #22| Main Road| Area XYZ,00000000
사용되는 다양한 긴 옵션의 짧은 변형은 -S
for --skipinitialspace
, -T
for --out-tabs
및 -t
for 입니다 --tabs
.