Unix 줄 끝에서 Windows 줄 끝을 변환하는 방법 (CR / LF에서 LF로)


80

저는 Java 개발자이고 Ubuntu를 사용하여 개발하고 있습니다. 이 프로젝트는 Eclipse와 함께 Windows에서 생성되었으며 Windows-1252 인코딩을 사용하고 있습니다.

UTF-8로 변환하려면 레코딩 프로그램을 사용했습니다 .

find Web -iname \*.java | xargs recode CP1252...UTF-8

이 명령은 다음 오류를 제공합니다.

recode: Web/src/br/cits/projeto/geral/presentation/GravacaoMessageHelper.java failed: Ambiguous output in step `CR-LF..data

나는 그것에 대해 검색하고 Bash 및 Windows, Recode : Ambiguous output in step`data..CR-LF ' 에서 솔루션을 얻었으며 다음 과 같이 말합니다.

줄 끝을 CR / LF에서 단일 LF로 변환 : Vim으로 파일을 편집하고 명령을 내리고 파일을 :set ff=unix저장합니다. 이제 Recode가 오류없이 실행되어야합니다.

좋지만 CR / LF 문자를 제거 할 파일이 많고 각 파일을 열 수 없습니다. Vi는 Bash 작업을위한 명령 줄 옵션을 제공하지 않습니다.

이를 위해 sed를 사용할 수 있습니까? 어떻게?


recodedos ( \r\n-CRLF) 및 unix ( \nLF) 개행 코딩 이 혼합 된 파일을 다시 코딩하려고 할 때이 오류가 발생 합니다. Unfortunatelly fromdos(이전 바이너리)는 현재이 문제가있는 레코딩의 별칭입니다.
— TMS

당신은 할 수 없어vim +ex_command_one +ex_command_two ... file
— derekdreery의

놀라운! awk답변 에는 해결책 이 없습니다 .
— Gerold Broser 2018

답변:


122

dos2unix줄 끝을 수정 하는 프로그램이 있어야 합니다. Linux 상자에없는 경우 패키지 관리자를 통해 사용할 수 있습니다.


2
fromdos 명령을 제공하는 tofrodos를 설치했지만 문제가 지속됩니다. fromdos -a GravacaoMessageHelper.java; recode CP1252 ... UTF-8 GravacaoMessageHelper.java 반환 : recode : GravacaoMessageHelper.java 실패 :`CR-LF..data '단계에서 모호한 출력
— MaikoID

1
@MaikoID : 그렇다면 더 큰 문제가 있습니다. CR은 변환 할 또 다른 문자 일 뿐이므로 recode는 어차피 줄 끝을 신경 쓰지 않아야합니다. 그리고 그것은 내 기계에 신경 쓰지 않는 것 같습니다.
— cHao 2010 년

1
fromdos는의 별칭 recode일 뿐이며 DOS (\ r \ n-CRLF) 및 유닉스 (\ n LF) 코딩이 혼합 된 파일에 언급 된 오류 OP를 생성합니다. dos2unix보편적으로 만 작동합니다.
— TMS

1
dos2unix는 homebrew를 통해 OS X에서 사용할 수 있습니다. "brew install dos2unix"
— Joseph Sheedy

1
후속 조치를 취하기 위해 동일한 문제가 발생하여 다음을 사용하게되었습니다 find ./ -name "*.java" -exec dos2unix {} +..
— amracel 19

85

sed는 라인이 패턴 공간에 들어가기 전에 후행 개행이 제거 되었기 때문에 \ n 일치 할 수 없지만 \ r과 일치 할 수 있으므로 \ r을 제거하여 \ r \ n (dos)를 \ n (unix)로 변환 할 수 있습니다.

sed -i 's/\r//g' file

경고: 원본 파일이 변경됩니다.

그러나 이것으로 unix EOL에서 dos 또는 old mac (\ r)으로 변경할 수 없습니다. 여기에 더 많은 읽기 :

sed를 사용하여 줄 바꿈 (\ n)을 어떻게 바꿀 수 있습니까?


4
+1 이것은 좋은 해결책입니다! 그러나 sed -i원본 파일이 변경 된다는 점에 유의해야 합니다 ! 사람들은 sed그렇게 행동 할 것으로 기대하지 않기 때문에 여기서 경고가 적절합니다. 많은 사람들이 알고 -i있기 때문에 sed -i ... file > file2원본 파일이 수정 될 것이라고 기대하지 않습니다.
— TMS

모든 sed변형이 비표준 기호 시퀀스를 인식하는 것은 아닙니다 \r. 이 경우 리터럴 ctrl-M 문자를 사용해보십시오 (많은 쉘에서 리터럴 제어 문자를 생성하려면 ctrl-V ctrl-M을 입력하십시오).
— tripleee

14

사실, vim은 당신이 찾고있는 것을 허용합니다. vim을 입력하고 다음 명령을 입력하십시오.

:args **/*.java
:argdo set ff=unix | update | next

이 명령 중 첫 번째는 인수 목록을 **/*.java모든 Java 파일 인 일치하는 모든 파일에 반복적으로 설정합니다. 두 번째 명령은 인수 목록의 각 파일에 대해 차례로 다음을 수행합니다.

  • 줄 끝을 Unix 스타일로 설정합니다 (이미 알고 있음).
  • 변경된 경우 파일을 작성합니다.
  • 다음 파일로 진행

이것은 dos2unixfor-loop에서 사용 하는 것보다 훨씬 느리지 만 Vim에서 수행하는 방법을 아는 것은 여전히 ​​좋습니다!
— jpaugh

2
I :: heart :: 내 정력. 감사합니다.
— Jono

9

tr 명령은 다음을 수행 할 수도 있습니다.

tr -d '\15\32' < winfile.txt > unixfile.txt

사용할 수 있어야합니다.

tr은 파일 이름으로 작동 할 수 없기 때문에 스크립트 내에서 실행해야합니다. 예를 들어 myscript.sh 파일을 만듭니다.

#!/bin/bash

for f in `find -iname \*.java`; do
    echo "$f"
    tr -d '\15\32' < "$f" > "$f.tr"
    mv "$f.tr" "$f"
    recode CP1252...UTF-8 "$f"
done

실행 myscript.sh하면 현재 디렉토리와 하위 디렉토리의 모든 Java 파일이 처리됩니다.


웹 -iname * .java를 찾기 위해 어떻게 적응할 수 있습니까? xargs는 CP1252 ... UTF-8을 레코딩합니다.
— MaikoID

tr은 파일 이름에서 작동하지 않으므로 bash 스크립트 내에서 실행해야합니다. 샘플 스크립트를 사용하여 답변을 편집하겠습니다.
— KeithL 2010 년

대답을 위해 Thnx하지만 오류가 지속됩니다 = | `CR-LF..data '단계의 모호한 출력
— MaikoID

7

jichao의 답변에 약간의 예외를 두겠습니다. 그가 방금 말한 모든 것을 상당히 쉽게 할 수 있습니다. 를 찾는 대신 \n줄 끝에서 캐리지 리턴을 찾으십시오.

sed -i 's/\r$//' "${FILE_NAME}"

unix에서 dos로 다시 변경하려면 줄의 마지막 문자를 찾아서 양식 피드를 추가하면됩니다. ( -rgrep 정규식을 사용하여 더 쉽게 추가 할 것입니다.)

sed -ri 's/(.)$/\1\r/' "${FILE_NAME}"

이론적으로 파일은 모든 행이 처리 될 때까지 첫 번째 행에 다음 입력 행을 추가하는 코드를 마지막 예제에 추가하여 mac 스타일로 변경할 수 있습니다. 하지만 여기서는 그 예를 만들지 않겠습니다.

경고 : -i는 실제 파일을 변경합니다. 백업을하려면 뒤에 문자열을 추가하십시오 -i. 그러면 기존 파일이 끝에 문자가 추가 된 동일한 이름의 파일로 이동합니다.


1
나는 당신의 제안을 좋아하지만 닫는 작은 따옴표가 누락되었습니다. sed -ri 's / (.) $ / \ 1 \ r /'$ {FILE_NAME}
— mgouin

1
@mgouin 주목 해 주셔서 감사합니다. 누락 된 작은 따옴표를 추가했습니다.
— John Chesshir

1
LF를 CRLF로 변환하는 경우 줄 끝 앞의 일부 마지막 문자를 캡처 할 필요가 없으며 성능에도 영향을 미칠 수 있습니다. 내 경우에는 그것을 할 충분 sed -i 's/$/\r/' ${FILE_NAME}...
— 토마스 도시

이 -r옵션은 이식 가능하지 않습니다. 당신 sed이 그것을 가지고 있지 않다면 시도해보십시오 -E.
— tripleee

5

극복하기 위해

Ambiguous output in step `CR-LF..data'

단순히 해결책은 -f변환을 강제 하기 위해 플래그를 추가하는 것 입니다.


0

여기에있는 Bryan Maupin 의 파이썬 스크립트 를 사용해 보셨습니까 ? (좀 더 일반적으로 수정했습니다)

#!/usr/bin/env python

import sys

input_file_name = sys.argv[1]
output_file_name = sys.argv[2]

input_file = open(input_file_name)
output_file = open(output_file_name, 'w')

line_number = 0

for input_line in input_file:
    line_number += 1
    try:  # first try to decode it using cp1252 (Windows, Western Europe)
        output_line = input_line.decode('cp1252').encode('utf8')
    except UnicodeDecodeError, error:  # if there's an error
        sys.stderr.write('ERROR (line %s):\t%s\n' % (line_number, error))  # write to stderr
        try:  # then if that fails, try to decode using latin1 (ISO 8859-1)         
            output_line = input_line.decode('latin1').encode('utf8')
        except UnicodeDecodeError, error:  # if there's an error
            sys.stderr.write('ERROR (line %s):\t%s\n' % (line_number, error))  # write to stderr
            sys.exit(1)  # and just keep going
    output_file.write(output_line)

input_file.close()
output_file.close()

해당 스크립트를 다음과 함께 사용할 수 있습니다.

$ ./cp1252_utf8.py file_cp1252.sql file_utf8.sql

-1

Windows로 돌아가서 Eclipse에 인코딩을 UTF-8로 변경 한 다음 Unix로 돌아가서 d2u파일에서 실행하도록 지시 하십시오.


많은 파일이 있다면,이 더 많은 작업을 할 수 있지만 당신은 ... 그것으로 넣어 기꺼이보다
— 조나단

d2u는 무엇이며 어디서 찾을 수 있습니까?
— Jesper Rønn-Jensen 2011

때때로 이름이 변경됩니다. Ubuntu가 fromdos10.04에서 호출하는 것처럼 보이며 패키지의 일부입니다 tofrodos.
— Jonathan
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.