일부 파일을 정규화하려고 하는데 SED와 일치하는 패턴을 찾을 수 없어 성공하지 못했습니다. Notepad++에서는 줄 끝에 CRLF가 명확하게 표시됩니다.
인쇄할 수 없는 문자를 볼 때^M와 cat
하나^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 솔루션의 작업을 이 스크립트의 상단에 추가 할 수 있습니다.
答え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さんも豊富な情報を提供してくれましたね。
それで、長く徹底した調査の終わりに、私は次の結論に達しました。最初の行はスペースが見つかるまで電子メールヘッダーを抽出し、2行目はスペースを正規化します。
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を使用できましたが、2番目のコマンドでは使用できなかった理由がわかりません(後で保存します)。