CSV에서 새 줄 문자를 제거하는 방법은 무엇입니까? csv는 파일 구분 기호(\u001C)를 구분 기호로 사용합니다.

CSV에서 새 줄 문자를 제거하는 방법은 무엇입니까? csv는 파일 구분 기호(\u001C)를 구분 기호로 사용합니다.

필드 구분 기호로 파일 구분 기호가 포함된 150개 이상의 열이 있는 CSV 파일이 있습니다. 문제는 열 중 하나에 개행 문자가 포함된다는 것입니다. 그러기 위해서는 이것들을 삭제하고 싶습니다.

입력 데이터

여기에 이미지 설명을 입력하세요.

출력 데이터

여기에 이미지 설명을 입력하세요.

답변1

출력에 hdFS 문자(16진수)를 표시하는 데 사용됩니다.1c

$ perl -0777 -pe 's/^(\d{3}.*)\n/$1/mg' input.txt | hd
00000000  30 30 31 1c 42 61 6b 65  72 20 53 74 2e 4c 6f 6e  |001.Baker St.Lon|
00000010  64 6f 6e 1c 33 1c 34 1c  37 0a 30 30 32 1c 50 65  |don.3.4.7.002.Pe|
00000020  6e 6e 79 20 4c 61 6e 65  4c 69 76 65 72 70 6f 6f  |nny LaneLiverpoo|
00000030  6c 1c 38 38 1c 35 1c 37  0a                       |l.88.5.7.|
00000039

그렇지 않은 경우 hd출력은 다음과 같습니다(FS 문자는 보이지 않지만 여전히 존재하므로~ 할 것이다-i다른 파일로 리디렉션되거나 "위치에서 편집" 옵션이 사용된 경우 출력에 있는 경우):

$ perl -0777 -pe 's/^(\d{3}.*)\n/$1/mg' input.txt   
001Baker St.London347
002Penny LaneLiverpool8857

두 경우 모두 이 Perl 스크립트는 전체 파일을 한 번에 읽고( -0777) 각 "줄"(3자리 숫자로 시작하여 다음 개행 문자를 포함하지 않는 일련의 문자)을 캡처한 다음 캡처된 텍스트로 바꿉니다. (개행 없음). 즉, 세 자리 숫자로 시작하는 "줄"에서 개행 문자를 제거합니다.

$1원하지 않는 개행 문자를 직접 제거하는 대신 공백으로 바꾸려면 RHS 뒤에 공백을 추가하세요. 또는 \x1c개행 문자를 FS 문자로 변경하려는 경우.

검색 s///및 바꾸기 작업에서는 m("여러 줄 문자열") 및 g("전역") 정규식 수정자를 사용합니다. g정규식(sed 포함)을 사용하고 정규식이 "전역" 반복 일치를 수행하도록 하는 여러 도구에 공통적이지만 mPerl에만 해당됩니다.

출처 man perlre("수정자" 섹션 검색):

m일치하는 문자열을 여러 줄로 처리합니다. 즉, 문자열의 첫 번째 줄의 시작과 마지막 줄의 끝을 일치시키는 것에서 문자열의 모든 줄의 시작과 끝을 일치시키는 ^것으로 변경합니다.$

참고 1: 이 스크립트는 "필드" 구분 기호가 무엇인지 상관하지 않습니다. 필드를 전혀 찾거나 사용하지 않습니다. 필드 구분 기호가 공백, 탭, 콜론 또는 기타 항목(물론 개행 문자 제외)인 경우에도 작동합니다.

참고 2: 원치 않는 개행 문자 다음에 오는 필드가 세 자리 숫자로 시작하는 경우 이 방법은 작동하지 않습니다 123 London. 이 문제를 처리하려면 입력 필드를 구문 분석하고 계산할 수 있는 더 복잡한 스크립트가 필요합니다.

답변2

당신은 그것을 사용할 수 있습니다 awk:

awk '{
  while (NF < 5  && getline cmp) { $0=$0"<br>"cmp }
  if (NF > 5) {
    print "#ERROR"
    count++
  }
  print
}
END{
  if (count) {
    print "FAILED "count" lines" > "/dev/stderr"
    exit 8
  }
}' FS=$'\x1c'
  • awk지정된 구분 기호가 있는 필드 구문 분석에 매우 적합
  • NF현재 행의 필드 수를 알려줍니다.
  • 줄 바꿈이 항상 두 번째 필드에 있도록 하고 언제 줄을 완성해야 하는지 알 수 있습니다. 다음 줄을 읽고 붙여넣기만 하면 됩니다. 공백으로 표시하는 것 <br>보다 낫습니다 . 정보를 잃습니다.
  • 줄의 마지막 필드에 개행 문자가 나타날 수 있으면 더 어려워지지만 어쨌든 이 스크립트는 오류를 포착하는 것이 안전합니다.

아스타?

답변3

사용행복하다(이전 Perl_6)

raku -e 'slurp.split("\x1C").join("\t").put;'  

입력 예(탭으로 구분):

~$ cat FS_test.txt
001 Baker St.
London  3   4   7
002 Penny Lane
Liverpool   88  5   7

~$ cat FS_test.txt | xxd
00000000: 3030 3109 4261 6b65 7220 5374 2e0a 4c6f  001.Baker St..Lo
00000010: 6e64 6f6e 0933 0934 0937 0a30 3032 0950  ndon.3.4.7.002.P
00000020: 656e 6e79 204c 616e 650a 4c69 7665 7270  enny Lane.Liverp
00000030: 6f6f 6c09 3838 0935 0937 0a              ool.88.5.7.

탭 문자를 다음으로 변환합니다 FS(MacOS의 View Hex 사용 xxd).

~$ raku -e 'slurp.split("\t").join("\x1C").put;' baker_st_FS_test.txt | xxd
00000000: 3030 311c 4261 6b65 7220 5374 2e0a 4c6f  001.Baker St..Lo
00000010: 6e64 6f6e 1c33 1c34 1c37 0a30 3032 1c50  ndon.3.4.7.002.P
00000020: 656e 6e79 204c 616e 650a 4c69 7665 7270  enny Lane.Liverp
00000030: 6f6f 6c1c 3838 1c35 1c37 0a0a            ool.88.5.7..

탭을 -로 변환하고 FS다시 되돌립니다( FS-to-tabs):

~$ cat FS_test.txt | raku -e 'slurp.split("\t").join("\x1C").put;' | raku -e 'slurp.split("\x1C").join("\t").put;'
001 Baker St.
London  3   4   7
002 Penny Lane
Liverpool   88  5   7


~$ cat FS_test.txt | raku -e 'slurp.split("\t").join("\x1C").put;' | raku -e 'slurp.split("\x1C").join("\t").put;' | xxd
00000000: 3030 3109 4261 6b65 7220 5374 2e0a 4c6f  001.Baker St..Lo
00000010: 6e64 6f6e 0933 0934 0937 0a30 3032 0950  ndon.3.4.7.002.P
00000020: 656e 6e79 204c 616e 650a 4c69 7665 7270  enny Lane.Liverp
00000030: 6f6f 6c09 3838 0935 0937 0a0a 0a         ool.88.5.7...

각 분할/병합 왕복은 파일 끝에 빈 줄을 추가합니다. .subst(/\n/, :nth(*))Final 앞에 루틴 호출을 삽입 하여 이러한 문제를 제거하십시오 .put. 또는 .trim-trailing슬러핑된 파일을 실행하여 후행 공백을 모두 제거하세요. (또한 hex 뷰어 아이디어를 제공한 @cas에게 감사드립니다).


부록: Raku의 trans포스트 루틴도 작동합니다:

raku -e 'slurp.trans("\x1C" => "\t").put;'

https://raku.org

관련 정보