grep untuk menemukan file yang mengandung ^ M (Windows carriage return)

72

Saya menggunakan Linux. Ada ^ M sial (Windows cariage return) di suatu tempat tersembunyi di ribuan file konfigurasi, dan saya harus menemukannya, karena itu membuat server gagal.

Bagaimana saya menemukan ^ M di antara hierarki direktori yang penuh dengan file konfigurasi?

Saya pikir saya tidak bisa memasukkan ^ M pada baris perintah bash. Tapi saya memilikinya di file teks yang saya sebut m.txt

Nicolas Raoul
sumber
Terkait: Hapus carriage return di Unix .
40XUserNotFound
windows akan menjadi ^ M ^ J
barlop
3
"Saya tidak bisa memasukkan ^ M di baris perintah bash". Ya kamu bisa. Coba control-V Control-M
Hennes

Jawaban:

92
grep -r $'\r' *

Gunakan -runtuk pencarian rekursif dan $''untuk c-style escape di Bash.

Terlebih lagi, jika Anda yakin itu file teks, maka itu harus aman untuk dijalankan

tr -d $'\r' < filename

untuk menghapus semua \rfile.

Jika menggunakan GNU sed, -idapat melakukan edit di tempat, jadi Anda tidak perlu menulis kembali:

sed $'s/\r//' -i filename
livibetter
sumber
10
@Nicolas: Anda dapat memasukkan ^ M di baris perintah dengan menekan ^ V ^ M, tetapi lebih baik digunakan $'\r'.
Dennis Williamson
Bagus, itu berhasil! Terima kasih untuk trik ^ V ^ M juga :-)
Nicolas Raoul
5
Di bawah Cygwin, -U diperlukan untuk membuat pekerjaan ini. Dan -n akan memberi tahu Anda nomor baris: grep -r -U -n -e $ '\ r'
Rainer Blome
4
Tambahkan -l ke perintah grep untuk hanya melihat nama file. Jika tidak, Anda mungkin akan dibombardir dengan garis yang cocok.
Brendan Byrd
1
@uprego tidak yakin jika Anda memahaminya sekarang, tetapi fyi dan lainnya, pencarian $'baca hit pertama di halaman manual bash(1), pada dasarnya, Anda dapat melihatnya seolah-olah Anda sedang menulis string literal C. Adapun command < filename, penggunaan <atau >disebut redirection , ini pertama kali saya melihat ada yang menyebutnya ekspresi yang lebih besar . Pencarian REDIRECTIONdi bash(1).
livibetter
12

Ketika saya mencoba, saya bisa tahu itu semacam bekerja, tetapi garis-garisnya kosong. Tambahkan opsi:

--color=never

Jika Anda mendapatkan masalah ini, saya pikir itu adalah karakter melarikan diri untuk menyoroti warna yang mengganggu \rkarakter.

Judson Wilson
sumber
2

Jika server Anda tidak memiliki bash shell, alternatifnya adalah menggunakan -fopsi aktif grep, dalam kombinasi dengan file yang disiapkan berisi \r.

Untuk membuat file:

$ echo -ne '\r' > /tmp/cr                    --or--                   $ printf '\r' > /tmp/cr

$ od -c /tmp/cr
0000000  \r
0000001

Untuk benar-benar melakukan pencarian

$ grep -f /tmp/cr *.html *.php *.asp *.whatever

atau Anda bisa sedikit malas dan cukup ketik *,

$ grep -f /tmp/cr *

The pilihan pada digunakan untuk menentukan file yang berisi pola untuk mencocokkan, satu per baris. Dalam hal ini hanya ada satu pola.-f filenamegrep

Kiwi Nick
sumber
2

Jika saya memahami pertanyaan Anda dengan benar, apa yang Anda inginkan adalah menormalkan semua akhir baris ke standar Unix LF ( \x0a). Itu tidak sama dengan hanya menghapus CRs ( \x0d) secara membabi buta .

Jika Anda memiliki beberapa file Mac yang hanya menggunakan CR untuk baris baru, Anda akan menghancurkan file-file itu. (Ya, Mac seharusnya menggunakan LF sejak hampir 20 tahun, tetapi masih ada (pada 2019) banyak aplikasi Mac yang hanya menggunakan CR).

Anda bisa menggunakan \R pelarian linebreak Perl untuk mengganti segala jenis baris baru dengan \n.

perl -i.bak -pe 's/\R/\n/g' $your_file

Ini akan menggantikan di tempat apapun linebreak dengan \ndi $your_file, menjaga cadangan dari file asli di ${your_file}.bak.

mivk
sumber
1

Untuk menggunakan grep pada karakter end-of-line, saya kira Anda harus memberi tahu grep bahwa file tersebut adalah biner.

-l (huruf L) hanya untuk mencetak nama file

-P adalah untuk perl regexp (jadi \ x0d diubah ke \ r atau ^ M)

grep -l --binary -P '\x0d' *
Vouze
sumber
0

Jika Anda menggunakan Mac dan menggunakan homebrew , Anda dapat melakukannya:

brew install tofrodos
fromdos file.txt

untuk menghapus semua pengembalian carriage Windows dari file.txt

Untuk beralih kembali ke pengembalian carriage Windows,

todos file.txt
kortina
sumber
untuk mencari di folder dan membersihkan semua file yang berasal dari dos, jalankan perintah ini: find. -type f -name "* .java" | xargs fromdos
Taiko
0

Dalam gaya ekspresi reguler, berbagai baris baru:

Windows (CR LF)
\r\n

Unix (LF)
\n

Karena \r\nurutannya cukup unik, saya pikir Anda harus dapat mencarinya dengan cara itu?

Untuk membuat segalanya lebih buruk, Mac dulu hanya memiliki 'r' di tempat baris baru. Saya tidak dapat memverifikasi ini, tetapi saya tidak berpikir generasi MacOSX melakukan itu lagi.

Mac Lama (CR)
\r

Jeff Atwood
sumber
Di direktori yang berisi m.txt, grep "\r\n" *tidak memberikan hasil. Tidak ada hasil baik untuk egrep -e "\r\n" *maupungrep -E "\r\n" *
Nicolas Raoul
@nicolas ah, saya salah paham .. yang Anda maksud hanya CR \rburuk saya. Baris baru windows penuh memang \r\natau CRLF
Jeff Atwood
0

Menindaklanjuti jawaban sebelumnya, metode 'tr' bagus:

533 $ if [[-n " tr -cd "\r" <~/.bashrc"]]; kemudian gema "DOS"; selain itu gema "UNIX"; fi

UNIX

534 $ if [[-n " tr -cd "\r" <dosfile.txt"]]; kemudian gema "DOS"; selain itu gema "UNIX"; fi

DOS

Malcolm Boekhoff
sumber