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.