줄 끝 문자

줄 끝 문자

일부 파일을 정규화하려고 하는데 SED와 일치하는 패턴을 찾을 수 없어 성공하지 못했습니다. Notepad++에서는 줄 끝에 CRLF가 명확하게 표시됩니다.

샘플 텍스트

인쇄할 수 없는 문자를 볼 때^Mcat하나^M 또는\r줄 끝.

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

메모장++에서 검색할 수 있습니다.\r\n\h+캐리지 리턴과 CC를 연결할 공백을 제거합니다. 모두 한 줄에 있습니다(때로는 여러 줄 바꿈이 있을 수 있음).

SED Whiteout으로 모든 조합을 성공적으로 시도한 것 같습니다. 저도 이 링크 확인했어요https://stackoverflow.com/questions/3569997/how-to-find-out-line-endings-in-a-text-file

내가 무엇을 놓치고 있나요?

실패한 시도의 예

sed -En 's/\r\s+//g' $NewFile
sed -En 's/\r +//g' $NewFile
sed -En 's/\r\n +//g' $NewFile
sed -En 's/\n +//g' $NewFile

답변1

쉬운 수정은 \r줄 끝에서 검색하는 정규식을 사용하는 것입니다( sed파일을 읽을 때 처리되지만 정규식 앵커를 사용하여 감지할 수 있음 $).

sed 's/\r$//' file.dos >file.txt

sed리터럴 지원이 없으면 스크립트 \r에 리터럴 캐리지 리턴을 포함하는 Bash "C 스타일" 문자열을 사용해 보세요 sed.

sed $'s/\r$//' file.dos >file.txt

...또는 기호 표현이 표준인 Awk를 사용하세요.

awk '{ sub(/\r$/, "") } 1' file.dos >file.txt

...또는 dos2unix논리를 바이너리로 캡슐화하는 이 도구를 사용하세요.

dos2unix file.dos

당신은 또한 볼 수 있습니다https://stackoverflow.com/questions/39527571/are-shell-scripts-sensitive-to-encoding-and-line-endings

이 전처리 후에 표준 이메일 도구를 사용하여 헤더를 추출할 수 있습니다. Procmail은 모든 헤더 행의 접기를 제공 formail -c하거나 추가할 수 있습니다 -z. 또는 간단한 Awk 단일 행을 사용할 수도 있습니다.

awk '!body { if(NR > 1 && $0 ~ /^[^ \n]/) printf "\n"; printf "%s", $0 }
  /^$/ { printf "\n"; body=1 }
  body'

물론 원한다면 sub이전 Awk 솔루션의 작업을 이 스크립트의 상단에 추가 할 수 있습니다.

데모:https://ideone.com/1z8uOU

답변2

sed는 기본적으로 한 번에 한 줄만 확인하고 버퍼에 개행 문자도 포함하지 않으므로 쉬운 방법은 s/\r\n/.../말할 것도 없고 그런 일도 할 수 없습니다. s/\r\n +//전체 파일을 한 번에 처리하도록 예약해야 합니다.

이것이 sed에서 쉽게 수행될 수 있는지는 확실하지 않지만 적어도 GNU sed에서는 -z개행 문자 대신 NUL 바이트를 구분 기호로 사용하는 옵션을 사용할 수 있습니다. 텍스트 파일에는 NUL이 있어서는 안 됩니다. 따라서 실제로는 전체 파일을 읽는 효과가 있습니다.

예를 들어 다음 입력 파일을 사용합니다.

$ cat -A foo.txt
from: foo bar^M$
to: someone ^M$
  someone else^M$
cc: something ^M$
   something else^M$
^M$

다음과 같이 작동할 수 있습니다.

$ sed -z -Ee 's/\r\n +//g' foo.txt |cat -A
from: foo bar^M$
to: someone someone else^M$
cc: something something else^M$
^M$

또는 옵션을 통해 전체 파일을 읽을 수 있는 Perl을 사용할 수도 있습니다 -0777.

$ perl -0777 -pe 's/\r\n +//g' foo.txt |cat -A
from: foo bar^M$
to: someone someone else^M$
cc: something something else^M$
^M$

하지만 이메일 헤더 처리에 대한 규칙이 무엇인지 잘 모르므로 이에 대해서는 언급하지 않겠습니다. 하지만 이메일 처리를 위한 도구/라이브러리/모듈이 이미 있다는 점에 유의하세요. 또한 동일한 파일에 메시지 데이터가 있는 경우 여기서 수행하는 작업도 메시지 데이터를 손상시킵니다.

답변3

우선, SED 사용 과정을 이해하는 것은 고사하고 이 작업을 완료할 수 없었더라도 저를 올바른 방향으로 안내하고 응답해 주신 모든 분들께 감사드립니다. @seshoumara가 제안한 대로 -z 옵션과 dos2unix 유틸리티를 사용해 보았지만 어떤 이유로 작동하지 않는 것 같습니다. @ilkkachu 님께서도 풍부한 정보를 제공해 주셨네요.

그래서 길고 철저한 조사 끝에 나는 다음과 같은 결론에 도달했습니다. 첫 번째 줄은 공백이 발견될 때까지 이메일 헤더를 추출하고, 두 번째 줄은 공백을 정규화합니다.

sed -n '0,/^\r/p' $f | tee bk/$NewFile  
sed -Ei ':Loop ; $!N ; s/\n\s+/ / ; tLoop ; P ; D' bk/$NewFile

줄 끝은 \r, \n 또는 \r\n을 사용할 때 가장 큰 문제였으며 dos2unix를 사용하면 그 문제가 해결되었습니다. 첫 번째 명령에서는 \r을 사용할 수 있었지만 두 번째 명령에서는 사용할 수 없었던 이유를 잘 모르겠습니다(나중에 저장하겠습니다).

관련 정보