몇 가지 레코드의 데이터가 새 행으로 이동되는 CSV 파일이 있습니다.
예:
ABCD,1234,QWER
ASDF
,2345,VGFT
"ASDF,12",1212,ASDR
1234,ZXCV,ERTT
출력은 다음과 같아야 합니다.
ABCD,1234,QWER
ASDF,2345,VGFT
"ASDF,12",1212,ASDR
1234,ZXCV,ERTT
두 번째와 세 번째 열을 결합하는 방법이 있나요?
답변1
다음은 주어진 데이터에 대해 작동하는 순진한 해킹입니다.
$ awk -F, 'NF != 3 { printf("%s",$0); getline } 1' file.csv
ABCD,1234,QWER
ASDF,2345,VGFT
1234,ZXCV,ERTT
그것이 하는 일은 awk
파일을 쉼표로 구분된 데이터 세트로 구문 분석하는 것입니다. 행에 정확히 세 개의 필드( )가 없으면 NF != 3
지금까지 읽은 행의 비트가 후행 개행 없이 있는 그대로 출력되고 다음 행이 읽혀집니다. Final 1
은 의 약어 { print }
이며 모든 줄을 인쇄합니다.
첫 번째 블록이 트리거된 경우 마지막 1
/는 print
출력이 끝날 때 나머지 중단 부분이 출력되도록 합니다 printf
.
그 변형은 다음과 같습니다 sed
:
$ sed -E '/^[^,]+,[^,]+,[^,]+$/!{ N; s/\n//; }' file.csv
ABCD,1234,QWER
ASDF,2345,VGFT
1234,ZXCV,ERTT
마찬가지로, 예제 데이터에 표시된 것과 다른 방식으로 줄이 바뀌면 이 기능이 작동하지 않을 수 있습니다.
이 sed
스크립트가 하는 일은 정규식을 사용하여 각 줄을 테스트하는 것입니다 ^[^,]+,[^,]+,[^,]+$
. 일치하는 경우 쉼표로 구분된 쉼표 이외의 문자로 구성된 세 개의 필드가 있는 것처럼 보이는 줄이 있습니다. 그렇다면아니요이 경우 다음 줄은 현재 줄의 끝에 추가되고 두 줄 사이에 삽입된 개행 문자는 N
제거됩니다.sed
코드 sed
는 코드와 동일한 논리를 따릅니다 awk
. 현재 행에 오류가 있으면 다음 데이터 행을 추가합니다.
답변2
유명한 라인 sed
의 변형 :
$ sed -e :a -e '$!N;s/\n[[:blank:]]*,/,/;ta' -e 'P;D' file.csv
ABCD,1234,QWER
ASDF,2345,VGFT
"ASDF,12",1212,ASDR
1234,ZXCV,ERTT
답변3
sed
다음과 같이 쉘 변수를 혼합하여 GNU에서 이를 수행할 수 있습니다 .
nF='[^,]*'; # a normal unquoted csv field
qF='"[^"]*"'; # a quoted csv field
F="\($qF\|$nF\)"; # a csv field
ok="$F,$F,$F\$"; # a csv record with exactly 3 fields
# ok="\($F,\)\{2\}$F\$"; # an equivalent way to write out the regex for an ok csv record
sed -e "
:a;/$ok/b
N;s/\n//;ba
" input.csv
산출
ABCD,1234,QWER
ASDF,2345,VGFT
"ASDF,12",1212,ASDR
1234,ZXCV,ERTT
~처럼
- sed에서 사용할 쉘 변수의 혼합을 사용하여 csv를 작성하기 위한 구문입니다.
- csv 레코드에는 3개 이하의 필드가 있다고 가정합니다.
- 먼저 csv 레코드가 정상인지, 즉 정확히 3개의 필드가 있는지 확인하세요. 이 경우 해당 레코드를 인쇄하고 다음 레코드를 읽으십시오.
- OTW, 즉 현재 csv 레코드에서 3개 미만의 필드가 발견되었습니다. 명령을 통해 다음 줄을 추가한
N
다음 커넥터 a를 제거\n
하고 이 수정된 패턴 공간을 사용하여 sed 코드의 맨 위로 분기합니다.