여러 학군에서 나에게 보낸 데이터를 구문 분석하는 Perl 스크립트가 있습니다. 새로운 학교를 추가하고 있는데 이전에 한 번도 겪어보지 못한 문제에 직면하게 되었습니다. 이렇게 하면 $line = <INPUT>
한 줄 대신 전체 파일을 먹습니다.
file
해당 파일을 실행하면 UTF-8 Unicode text, with CRLF, CR line terminators
다른 모든 파일이 반환 됩니다 ASCII text, with CRLF line terminators
. dos2unix를 통해 실행했지만 여전히 긴 문자열로 실행됩니다. Emacs에서 편집해도 여전히 ^M이 줄 끝으로 표시됩니다.
이 줄 끝을 사용 가능한 줄 끝으로 어떻게 변환합니까?
고쳐 쓰다: 공급업체에서 줄 끝이 다른 다른 파일을 보냈는데 여전히 작동하지 않습니다. CRLF, LF로 보고됩니다. 나는몇 가지 샘플 라인.
내 코드의 일부 조각은 다음과 같습니다.
$line = <INPUT> if ($schooldistricts{$schooldistrict}{'header'});
LINE: foreach $line (<INPUT>) {
next LINE unless ($line =~ /\S/);
<do stuff>
}
파일에 적절하게 제거된 헤더가 있습니다. 그런 다음 foreach 루프에서 첫 번째 줄을 성공적으로 읽습니다. 그게 전부입니다. 파일의 나머지 부분이 비어 있는 것과 같습니다.
$/
설정 을 시도했지만 \r\n\n
스크립트는 아무 작업도 수행하지 않았습니다. 내가 시도해도 마찬가지다 \r\n
. 줄 끝에 어떤 문자가 인코딩되어 있는지 명시적으로 확인할 수 있는 방법이 있나요?
두 번째 업데이트: 실험적으로 파일을 엑셀로 가져와서 분할한 후 탭으로 구분된 파일로 저장해 보았습니다. 서버에서 dos2unix를 실행합니다. Perl 스크립트는 두 번째 줄 이후에도 여전히 구문 분석할 수 없습니다. File
지금 돌아가세요 UTF-8 Unicode text, with CRLF line terminators
. 이것이 올바른 줄 끝이므로 유니코드가 문제입니다. 유니코드는 줄 끝을 다르게 인코딩합니까?
답변1
perl -pi -e 's/\r\n?/\n/g' your-file
mac2unix
or 연산 과 유사하게 CR 문자(선택적으로 LF가 뒤따름)를 LF로 변환합니다 dos2unix -c mac
.
또는:
perl -pi -e 's/\r\n?/\r\n/g' your-file
이것이 스크립트에서 예상하는 것이라면 CRLF로 변환하십시오(예를 들어 $/
입력 레코드 구분 기호를 로 설정하기 때문입니다 "\r\n"
).
답변2
이 파이프는 CR 문자 또는 CR/LF 시퀀스를 LF로 변환합니다.
tr '\r\n' '\n\r' | sed 's/^\r//g' | tr '\r' '\n'
답변3
사용행복하다(이전 Perl_6)
OP가 문제가 유니코드 기반이라고 생각하는 경우 Raku가 기본적으로 UTF-8을 처리하므로 Raku 스크립트를 사용하는 것이 도움이 될 수 있습니다.
~$ cat dos2unix.raku
my $fh1 = open $*IN, :r;
#below use :w (write-only) or :x (:x write-only :exclusive i.e. 'no-clobber')
my $fh2 = open $*OUT, :x, nl-out => "\n";
for $fh1.lines() { $fh2.put($_) };
$fh1.close;
$fh2.close;
위 파일을 스크립트(예: "dos2unix.raku")에 저장하고 shebang 줄을 추가하여 실행 가능하게 만듭니다. 또는 명령줄에서 호출하면 됩니다.
~$ raku dos2unix.raku < ends_with_CRLF.txt > ends_with_LF.txt
DOS 줄 끝이 있는 입력 예( 0d 0a
줄당):
~$ jot -w '%d' 5 | raku unix2dos.raku | hexdump -C
00000000 31 0d 0a 32 0d 0a 33 0d 0a 34 0d 0a 35 0d 0a |1..2..3..4..5..|
Unix 줄 끝으로 변환된 출력 예( 0a
줄당):
~$ jot -w '%d' 5 | raku unix2dos.raku | raku dos2unix.raku | hexdump -C
00000000 31 0a 32 0a 33 0a 34 0a 35 0a |1.2.3.4.5.|
0000000a
위의 내용은 실제 Unix 줄 끝( 0a
줄당)을 복제합니다.
~$ jot -w '%d' 5 | hexdump -C
00000000 31 0a 32 0a 33 0a 34 0a 35 0a |1.2.3.4.5.|
0000000a
위 스크립트가 작동하지 않으면 정규식 솔루션이 slurp
ed 파일에 도움이 될 \v
수 있습니다(수직 공백). Raku는 Raku Regex 방언의 줄 경계에 대한 유니코드 정의를 존중한다고 주장합니다. https://unicode.org/reports/tr18/#Line_Boundaries.
~$ raku -e 'slurp.subst(:global, / \v /, "\n").chop.put;' file
#OR
~$ raku -e 'slurp.subst(:global, / <+ :Zl + :Zp> /, "\n").chop.put;' file
아래 첫 번째 링크의 스크립트를 참조하세요 unix2dos.raku
(즉, 반대 답변).
인용하다:
https://unix.stackexchange.com/a/743445/227738
https://docs.raku.org/언어/newline.html
https://raku.org