유닉스로 병합

유닉스로 병합

|아래와 같이 구분 기호로 파이프( )가 있는 CSV 파일이 있는데 Unix에서 병합 기술을 적용해야 합니다. 파일에는 수십만 개의 레코드(4개 필드)가 포함되어 있지만 가독성을 위해 5개의 레코드만 제공했습니다.

field1 |field2 | field3 |field4|
1|abc|def|ghi|
4|ijk|
|lmn|
5||opq|rst|
8|
uvw||xyz|
10|hjg|jsh|nbm|

나는 출력을 원한다.

field1|field2|field3|field4|
1|abc|def|ghi|
4|ijk||lmn|
5||opq|rst|
8|uvw||xyz|
10|hjg|jsh|nbm|

답변1

GNU sed 사용:

sed ':loop /\(.*|\)\{4\}.*/ !{N; s/\n//; b loop}; s/ *| */|/g' file

이 명령의 분석:

:loop

:신호는 분기에 사용할 수 있는 레이블을 나타냅니다. "loop"는 제가 레이블로 선택한 이름입니다.

/\(.*|\)\{4\}.*/

4개의 파이프 기호가 포함된 라인과 일치하는 라인 선택기 정규 표현식입니다. 각 파이프 기호 앞에는 0개 이상의 임의 문자가 허용되고( .*|) 마지막 파이프 뒤에는 0개 이상의 임의 문자가 허용됩니다.

!{ ... }

실행된 모든 행에 괄호 안의 명령을 적용합니다.아니요이전 정규식을 일치시킵니다.

N; s/\n//; b loop

N현재 행에 합류패턴 공간소스 파일에서 줄 바꿈과 다음 줄을 사용하여 s/\n//줄 바꿈을 제거하고 b loop처음에 정의한 레이블로 다시 분기하면 연결된 줄이 정규식과 다시 비교됩니다.

마침내

s/ *| */|/g

출력하기 전에 패턴 공간의 모든 라인에 적용됩니다. 이렇게 하면 파이프 기호 주위의 모든 공백이 제거됩니다.

답변2

나는 당신이 빈 줄을 모두 원하지 않는다고 가정합니다.

$ cat file
1|abc|def|ghi|
4|ijk|
|lmn|
5||opq|rst|
8|
uvw||xyz|
10|hjg|jsh|nbm|

$ awk -F'|' '{while (NF < 5) {getline nextline; $0 = $0 nextline}}1' file
1|abc|def|ghi|
4|ijk||lmn|
5||opq|rst|
8|uvw||xyz|
10|hjg|jsh|nbm|

질문 편집 업데이트: 필드 구분 기호 주위의 공백 제거

awk -F'[[:blank:]]*[|][[:blank:]]*' -v OFS='|' '
    {while (NF < 5) {getline nextline; $0 = $0 nextline}; $1=$1; print} 
' file

답변3

Vim을 사용하는 것이 옵션인 경우:

vim -Nesc 'g!/\(.*|\)\{4\}$/j!' -cwq input.txt
  • -Nes더 쉬운 자동화를 위해 스크립트 모드에서 Vim을 실행하세요
  • -c ...파일을 열고 Vim 명령을 실행하세요.
  • g!/\(.*|\)\{4\}$/j!- 각 라인:g, 저것아니요 !일치 /\(.*|\)\{4\}$/(4개 파이프와 일치하는 정규식, 무엇이든 구분), 다음 줄을 연결합니다(:j).
  • wq- 저장 및 종료.

관련 정보