Saya perlu secara berkala menjalankan perintah yang memastikan bahwa beberapa file teks disimpan dalam mode Linux. Sayangnya dos2unix
selalu memodifikasi file, yang akan mengacaukan cap waktu file dan folder dan menyebabkan penulisan yang tidak perlu.
Script yang saya tulis ada di Bash, jadi saya lebih suka jawaban berdasarkan Bash.
bash
text-processing
newlines
Adam Ryczkowski
sumber
sumber
test
denganmyfile.txt
dua kali dalam contoh Anda untuk menghindari kebingungan/usr/bin/test
.-s
flag untuk melihat hasilnya. Dari halaman manual:-s, --quiet, --silent suppress all normal output
Jika tujuannya hanya untuk menghindari memengaruhi timestamp,
dos2unix
memiliki opsi-k
atau--keepdate
yang akan menjaga timestamp tetap sama. Masih harus menulis untuk membuat file sementara dan mengganti nama, tetapi cap waktu Anda tidak akan terpengaruh.Jika modifikasi file tidak dapat diterima, Anda dapat menggunakan solusi berikut dari jawaban ini .
sumber
find ... -exec file ... | grep CRLF
untuk file dengan akhiran garis DOS (yaitu byte 0D 0A) "akan membuat Anda mendapatkan sesuatu seperti:./1/dos1.txt: ASCII text, with CRLF line terminators
Seperti yang Anda lihat ini berisi string CRLF yang sebenarnya dan karenanya dicocokkan dengangrep
mencari string sederhana CRLFAnda dapat mencoba
grep
kode CRLF, oktal:atau hex:
sumber
grep
penggunaan ini karena memungkinkan saya untuk dengan mudah mendaftarkan semua file seperti itu di direktori dengangrep -lU $'\x0D' *
dan meneruskan output kexargs
.Karena versi
7.1
dos2unix memiliki-i
,--info
opsi untuk mendapatkan informasi tentang jeda baris. Anda dapat menggunakan dos2unix itu sendiri untuk menguji file mana yang perlu konversi.Contoh:
sumber
Metode pertama (
grep
):Hitung garis yang mengandung carriage return:
Hitung garis yang berakhir dengan carriage return:
Ini biasanya akan setara; kembalinya carriage di bagian dalam garis (yaitu, bukan di akhir) jarang terjadi.
Lebih efisien:
Ini lebih efisien
grep -c
perlu membaca seluruh file, untuk menghitung semua kemunculan pola, sementaragrep -q
dapat keluar setelah melihat kemunculan pola pertama.Catatan:
-U
opsi (yaitu, gunakan-cU
atau-qU
), karena GNUgrep
menebak apakah file tersebut adalah file teks. Jika ia berpikir file tersebut adalah teks, ia mengabaikan carriage return di akhir baris, dalam upaya membuat$
ekspresi reguler berfungsi "dengan benar" - bahkan jika ekspresi regulernya adalah\r$
! Menentukan-U
(atau--binary
) mengesampingkan dugaan ini, menyebabkangrep
memperlakukan file sebagai biner dan meneruskan data ke mekanisme pencocokan kata demi kata, dengan CR-endings utuh.grep … $'\r\n' myfile.txt
, karenagrep
memperlakukan\n
sebagai pembatas pola. Sama sepertigrep -E 'foo|'
mencari baris yang berisifoo
atau string nol,grep $'\r\n'
mencari baris yang berisi\r
atau string nol, dan setiap baris cocok dengan string nol.Metode kedua (
file
):karena
file
melaporkan sesuatu seperti:Varian yang lebih aman:
dimana
file -b
hanya menghasilkan jenis file, dan bukan nama file. Tanpa ini, file yang namanya termasuk karakterCRLF
akan memicu false positive.file - < filename
bekerja bahkan jikafilename
dimulai dengan-
. Lihat skrip Bash: periksa apakah file adalah file teks .Berhati-hatilah karena memeriksa output dari
file
mungkin tidak berfungsi di lokal non-Inggris.sumber
"$(echo -e '\r')"
dengan yang lebih sederhana$'\r'
, meskipun secara pribadi saya akan gunakan$'\r\n'
untuk mengurangi jumlah false positive.grep $'\r\n'
tampaknya cocok dengan semua file di sistem saya ...grep -U $'\r$'
, untuk mencegahgrep
mencoba menebak garis akhir.-q
untuk hanya mengatur kode kembali jika kecocokan ditemukan, alih-alih-c
yang membutuhkan pemeriksaan tambahan. Secara pribadi saya suka solusi kedua Anda, meskipun itu sangat tergantung pada keinginanfile
dan mungkin tidak bekerja di lokal non-Inggris.Menggunakan
cat -A
Sekarang jika file ini dibuat dalam sistem * NIX, itu akan ditampilkan
Tetapi jika file ini dibuat di Windows, itu akan ditampilkan
^M
mewakiliCR
dan$
mewakiliLF
. Perhatikan bahwa Windows tidak menyimpan baris terakhir denganCRLF
Ini tidak mengubah isi file juga.
sumber
-A
untuk kucing. Namun satu tip akan digunakancat -A file | less
jika file terlalu besar. Saya yakin itu tidak biasa harus memeriksa ujung file untuk file yang sangat panjang. (Tekanq
untuk meninggalkan lebih sedikit)fungsi bash untuk Anda:
Maka Anda dapat melakukan hal-hal seperti
sumber
isDosFile()
dalam contoh Anda:streamFile() { sed 's/\r$//' "$1" ; }
.Jika sebuah file memiliki akhiran garis CR-LF gaya DOS / Windows, maka jika Anda melihatnya menggunakan alat berbasis Unix Anda akan melihat karakter CR ('\ r') di akhir setiap baris.
Perintah ini:
akan mencetak
filename
jika file berisi satu atau lebih baris dengan ujung garis bergaya Windows, dan tidak akan mencetak apa pun jika tidak. Kecuali bahwa^M
harus menjadi karakter carriage return literal, biasanya dimasukkan di terminal dengan mengetik Ctrl+ Vdiikuti oleh Enter (atau Ctrl+ Vdan kemudian Ctrl+ M). Bash shell memungkinkan Anda menulis carriage return secara literal seperti$'\r'
( didokumentasikan di sini ), sehingga Anda dapat menulis:Kerang lain mungkin menyediakan fitur serupa.
Anda dapat menggunakan alat lain sebagai gantinya:
Ini akan keluar dengan status
1
(pengaturan$?
ke1
) jika file tersebut berisi ujung garis gaya Windows, dan dengan status0
jika tidak, menjadikannya berguna dalamif
pernyataan shell (perhatikan kurangnya[
tanda kurung]
):File dapat berisi campuran akhiran gaya Unix dan gaya Windows. Aku menduga di sini bahwa Anda ingin mendeteksi file yang memiliki setiap Windows gaya akhir baris.
sumber
$'\r'
, seperti yang disebutkan dalam jawaban lain untuk pertanyaan ini.Gunakan
file
:sumber
Saya telah menggunakan
yang sepertinya berhasil. Saya menemukan output sedikit lebih mudah dibaca daripada
Ini juga berguna jika Anda tidak dapat menginstal
dos2unix
karena suatu alasan.sumber