Jak zbiorczo przekonwertować cały plik w gałęzi systemu plików między formatem podziału wiersza Unix i Windows?

14

Wszyscy wiedzą :-), że w Windows zwykłe pliki tekstowe kończą się na CR + LF, aw Unix i Linux - tylko na LF. Jak mogę szybko przekonwertować wszystkie pliki kodu źródłowego z jednego formatu na inny iz powrotem?

Ivan
źródło

Odpowiedzi:

17

To zależy: jeśli pliki są pod kontrolą wersji, może to być dość niepopularna decyzja, która zanieczyszcza historię. Git ma opcję automatycznej konwersji zakończeń linii przy kasie.

Jeśli nie obchodzi Cię to i chcesz szybko przekonwertować, istnieją programy takie jak fromdos/ todosi dos2unix/, unix2dosktóre robią to za Ciebie. Można użyć find: find . -type f -name '*.php' -exec dos2unix '{}' +.

janmoesen
źródło
7

Istnieje kilka dedykowanych programów, w tym

  • dos2unixoraz unix2dosz narzędzi dos2unix
  • todosoraz fromdosz narzędzi tofrodos

Po prostu wybierz narzędzie dla odpowiedniego kierunku i podaj nazwy plików do konwersji w wierszu poleceń.


Jeśli nie masz, ale masz Linux lub Cygwin:

sed -i -e 's/\r\+$//' filename             # dos|unix -> unix
sed -i -e 's/\r*$/\r/' filename            # dos|unix -> dos

Jeśli masz perla:

perl -i -pe 's/\r+$//' filename            # dos|unix -> unix
perl -i -pe 's/\r*$/\r/' filename          # dos|unix -> dos

Przy użyciu tylko narzędzi POSIX (w tym BusyBox), aby przejść z unixa na dos, musisz przekazać znak CR dosłownie w poleceniu sed.

cr=$(echo | tr '\n' '\r')
sed -e "s/$cr*\$/$cr/" <filename >filename.dos
mv filename.dos filename

W przeciwnym kierunku możesz po prostu usunąć wszystkie CR:

tr -d '\r' <filename >filename.dos
mv filename.dos filename

Za pomocą symboli wieloznacznych można konwertować wiele plików w tym samym katalogu jednocześnie, np

sed -i -e 's/\r\+$//' *.txt

Aby przekonwertować wszystkie pliki w bieżącym katalogu i jego podkatalogach, jeśli twoją powłoką jest zsh, możesz użyć **/np

sed -i -e 's/\r\+$//' **/*.txt

Możesz użyć **/w bash ≥4, ale musisz shopt -s globstarnajpierw uruchomić (możesz umieścić tę linię w swoim ~/.bashrc). Możesz użyć **/w ksh93, ale najpierw musisz uruchomić set -o globstar(możesz umieścić tę linię w swoim ~/.kshrc.

Jeśli możesz korzystać tylko z narzędzi wymagających przekierowania, użyj forpętli.

for x in *.txt; do
  tr -d '\r' <"$x" >"$x.dos"
  mv -- "$x.dos" "$x"
done

Jeśli nie masz **/lub potrzebujesz bardziej złożonego dopasowania, aby wybrać pliki do konwersji, użyj findpolecenia. Oto przykład Linux / Cygwin, który konwertuje wszystkie pliki w bieżącym katalogu i jego podkatalogach rekurencyjnie, z wyjątkiem plików wywoływanych .oi podkatalogów bin.

find -name 'bin' -type d -prune -o \
     \! -name '*.o' \
     -exec sed -i -e 's/\r\+$//' {} +

Oto przykład POSIX. Mówimy, findaby uruchomić powłokę, która może wykonać niezbędne przekierowanie.

find -name 'bin' -type d -prune -o \
     \! -name '*.o' \
     -exec sh -c '
       tr -d '\r' <"$0" >"$0.dos"
       mv -- "$0.dos" "$0"
' {} \;

Możesz uczynić tę findmetodę nieco szybszą, kosztem bardziej złożonego kodu, używając pętli w poleceniu powłoki.

find -name 'bin' -type d -prune -o \
     \! -name '*.o' \
     -exec sh -c '
       for x; do
         tr -d '\r' <"$x" >"$x.dos"
         mv -- "$x.dos" "$x"
       done
' _ {} +
Gilles „SO- przestań być zły”
źródło
2

winscp również automatycznie przekonwertuje, jeśli zostanie o to poproszony .

Jeśli wszystkie pliki znajdują się w tym samym katalogu:

DIRECTORY=/your/directory
unix2dos $DIRECTORY/*
Nils
źródło
Czy możesz opisać nieco więcej, jak to osiągnąć dzięki WinSCP?
harish sharma
@harishsharma Dodałem link obove do „powiedzieć tak”.
Nils