2010-10-08 13 views
52

Jestem programistą Java i używam Ubuntu do rozwoju. Projekt został stworzony w systemie Windows z Eclipse i wykorzystuje kodowanie CP1252.Jak przekonwertować koniec systemu Windows na końcu linii (CR/LF na LF)?

Aby przekonwertować na UTF-8 Użyłem programu recode:

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

to polecenie daje ten błąd:

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

Mam serached o tym i uzyskać rozwiązanie tutaj: http://fvue.nl/wiki/Bash_and_Windows#Recode:_Ambiguous_output_in_step_.60data..CR-LF.27 i mówi:

Convert line endings from CR/LF to a single LF: Edit the file with vim , give the command :set ff=unix and save the file. Recode now should run without errors.

ładne, ale mam wiele plików, aby usunąć znak CR/LF, Nie mogę otworzyć każdego, aby to zrobić. Vi nie udostępnia opcji wiersza poleceń dla operacji basha.

sed może być do tego użyty? W jaki sposób ?

Thankx =)

+0

'recode' produkuje ten błąd podczas próby przekodowania pliku z mieszanym kodowaniem dos (' \ r \ n' - CRLF) i uniksem ('\ n' LF). Niestety 'fromdos', poprzednio binarny, jest obecnie aliasem do recode, który ma ten problem. – TMS

+0

Nie możesz zrobić "vim + ex_command_one + ex_command_two ... file' – derekdreery

Odpowiedz

87

Nie powinno być program o nazwie dos2unix który naprawia końca linii dla Ciebie. Jeśli nie znajduje się już na twoim Linux-ie, powinien być dostępny przez menedżera pakietów.

+2

Mam zainstalowane tofrodos, które zapewniają polecenie fromdos, ale problem nadal występuje. fromdos -a GravacaoMessageHelper.java; recode CP1252 ... UTF-8 GravacaoMessageHelper.java zwraca: recode: GravacaoMessageHelper.java failed: Niejednoznaczne wyjście w kroku 'CR-LF..data ' – MaikoID

+2

+1 za podanie dos2unix. – Bernard

+0

@MaikoID: Wtedy masz większe problemy. recode nie powinno w ogóle obchodzić końca linii, ponieważ CR jest po prostu kolejną postacią do konwersji. I wydaje się, że nie obchodzi mnie to na mojej maszynie. – cHao

8

Polecenie tr może też to zrobić:

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

i powinny być dostępne dla Ciebie.

Musisz uruchomić tr z poziomu skryptu, ponieważ nie może działać z nazwami plików. Na przykład utworzyć myscript.sh pliku:

#!/bin/bash 

cd ${1} 
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 

Running myscript.sh Web będzie przetwarzać wszystkie pliki Java w folderze Web.

+0

jak mogę się przystosować, aby znaleźć Web -iname \ *. Java | xargs recode CP1252 ... UTF-8 – MaikoID

+0

Będziesz musiał uruchomić tr w skrypcie basha, ponieważ nie może działać na nazwach plików. Będę edytować moją odpowiedź za pomocą przykładowego skryptu. – KeithL

+0

Thnx za odpowiedź, ale błąd nadal występuje = | Niejednoznaczne dane wyjściowe w kroku 'CR-LF..data ' – MaikoID

0

Wróć do systemu Windows, powiedz Eclipse, aby zmienić kodowanie na UTF-8, a następnie z powrotem do systemu Unix i uruchom d2u na plikach.

+0

Chociaż jeśli jest dużo plików, może to być więcej pracy niż jesteś w stanie w nią umieścić ... – Jonathan

+0

Co to jest d2u i gdzie go znaleźć? –

+0

Od czasu do czasu zmieniana jest nazwa. Wygląda na to, że Ubuntu nazywa go 'fromdos' w wersji 10.04 i jest częścią pakietu' tofrodos'. – Jonathan

0

Czy próbowałeś python script by Bryan Maupin found here? (I zostały zmodyfikowane go trochę być bardziej ogólne)

#!/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() 

Można użyć tego skryptu z

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

W celu przezwyciężenia

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

prostu rozwiązaniem mogłoby być dodaj flagę -f, aby wymusić konwersję.

+0

to działało dla mnie! – pdwalker

60

sed nie może dopasować \ n ponieważ końcowa nowa linia jest usuwana przed linia jest umieszczana w obszarze wzorca, ale może pasować do \ r, więc możesz przekonwertować \ r \ n (dos) na \ n (unix), usuwając \ r

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

Ostrzeżenie: to zmieni oryginalny plik

jednak nie można zmienić z unix EOL do DOS lub starego Mac (\ R) od tego. Więcej odczyty tutaj:

How can I replace a newline (\n) using sed?

+3

+1 To miłe rozwiązanie! Ale powinieneś zauważyć, że ** 'sed -i' zmieni oryginalny plik **! Ponieważ ludzie nie oczekują, że "sed" zachowa się tak, więc ostrzeżenie jest tutaj odpowiednie. Niewiele osób wie "-i", więc spróbuje 'sed -i ... file> file2' i nie spodziewa się, że oryginalny plik zostanie zmodyfikowany. – TMS

13

Właściwie vim zezwala co szukasz. Wprowadź vim i wpisz następujące polecenia:

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

Pierwszy z tych poleceń ustala listę argumentów do każdego pliku pasującego **/*.java, czyli wszystkie pliki Java, rekurencyjnie. Drugi z tych poleceń wykonuje następujące do każdego pliku w liście argumentów, z kolei:

  • Ustawia line-zakończeń do stylu Unix (już o tym wiedzą)
  • Zapisuje plik z IFF, że został zmieniony
  • przejście do następnego pliku
+0

Idealne rozwiązanie! – Helbreder

+0

Jest to prawdopodobnie znacznie wolniejsze niż użycie 'dos2unix' w pętli for, ale nadal dobrze jest wiedzieć, jak to zrobić w Vimie! – jpaugh

+0

I :: heart :: my vim. Dziękuję Ci za to. – jQwierdy

2

wezmę trochę wyjątek odpowiedź jichao użytkownika. W zasadzie możesz z łatwością zrobić wszystko, o czym mówił. Zamiast szukać \ n, po prostu szukaj pliku danych na końcu wiersza.

Aby przejść z systemu Unix z powrotem do Dos, wystarczy poszukać ostatniego znaku na linii i dodać do niego kanał. (Dodam -r aby to łatwiejsze z grep wyrażeń regularnych.)

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

Teoretycznie, plik może zostać zmieniona na stylu mac poprzez dodanie kodu do ostatniego przykładu, który również dołącza następną linię wejścia do pierwszy wiersz, dopóki wszystkie linie nie zostaną przetworzone. Nie będę tu jednak próbował tego przykładu.

Ostrzeżenie: -i zmienia rzeczywisty plik. Jeśli chcesz utworzyć kopię zapasową, dodaj ciąg znaków po -i. Spowoduje to przeniesienie istniejącego pliku do pliku o tej samej nazwie z dodanymi znakami na końcu.

Powiązane problemy