Bagaimana cara mengonversi secara massal semua file dalam cabang sistem file antara Unix dan format Windows line break?

14

Semua orang tahu :-) bahwa di Windows file teks biasa diakhiri dengan CR + LF, dan di Unix & Linux - hanya dengan LF. Bagaimana saya bisa dengan cepat mengkonversi semua file kode sumber saya dari satu format ke format lain dan kembali?

Ivan
sumber

Jawaban:

17

Itu tergantung: jika file berada di bawah kontrol versi, ini bisa menjadi keputusan pencemaran sejarah yang agak tidak populer. Git memiliki opsi untuk mengonversi ujung jalur secara otomatis saat check-out.

Jika Anda tidak peduli dan ingin mengonversi dengan cepat, ada program seperti fromdos/ todosdan dos2unix/ unix2dosyang melakukan ini untuk Anda. Anda dapat menggunakan find: find . -type f -name '*.php' -exec dos2unix '{}' +.

janmoesen
sumber
7

Ada beberapa program khusus, termasuk

Cukup pilih alat untuk arah yang sesuai dan berikan nama file untuk dikonversi pada baris perintah.


Jika Anda tidak memiliki keduanya, tetapi miliki Linux atau Cygwin:

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

Jika Anda memiliki perl:

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

Dengan hanya alat POSIX (termasuk BusyBox), untuk beralih dari unix ke dos, Anda harus melewati karakter CR secara harfiah dalam perintah sed.

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

Di arah lain, Anda cukup menghapus semua CR:

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

Anda dapat menggunakan wildcard untuk mengonversi banyak file dalam direktori yang sama sekaligus, misalnya

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

Untuk mengonversi semua file dalam direktori saat ini dan subdirektori, jika shell Anda zsh, Anda dapat menggunakan **/, misalnya

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

Anda dapat menggunakan **/dalam bash ≥4, tetapi Anda harus menjalankan shopt -s globstarterlebih dahulu (Anda dapat meletakkan baris ini di Anda ~/.bashrc). Anda dapat menggunakan **/di ksh93, tetapi Anda harus menjalankannya set -o globstarterlebih dahulu (Anda dapat meletakkan baris ini di ~/.kshrc.

Jika Anda hanya bisa menggunakan alat yang memerlukan pengalihan, gunakan forloop.

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

Jika Anda tidak memiliki **/atau membutuhkan pencocokan yang lebih kompleks untuk memilih file mana yang akan dikonversi, gunakan findperintah. Berikut adalah contoh Linux / Cygwin yang mengubah semua file di bawah direktori saat ini dan subdirektori secara rekursif, kecuali untuk file yang dipanggil .odan di bawah subdirektori yang disebut bin.

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

Inilah contoh POSIX. Kami meminta finduntuk memulai shell yang dapat melakukan redirection yang diperlukan.

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

Anda dapat membuat findmetode ini sedikit lebih cepat, dengan mengorbankan kode yang lebih kompleks, dengan menggunakan loop pada perintah shell.

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 'SANGAT berhenti menjadi jahat'
sumber
2

winscp juga akan otomatis dikonversi, jika diberitahu demikian .

Jika file Anda berada di direktori yang sama:

DIRECTORY=/your/directory
unix2dos $DIRECTORY/*
Nils
sumber
Bisakah Anda jelaskan sedikit lebih banyak, bagaimana mencapainya melalui WinSCP?
harish sharma
@harishsharma saya menambahkan tautan di atas ke "bilang begitu".
Nils