grep để tìm các tệp có chứa ^ M (Windows return return)


72

Tôi sử dụng Linux. Có một điều đáng tiếc ^ M (Windows cariage return) ở đâu đó ẩn trong hàng ngàn tệp cấu hình và tôi phải tìm nó, vì nó làm cho máy chủ bị lỗi.

Làm cách nào để tìm ^ M trong một phân cấp thư mục chứa đầy các tệp cấu hình?

Tôi nghĩ rằng tôi không thể nhập ^ M trên dòng lệnh bash. Nhưng tôi có nó trong một tệp văn bản mà tôi gọi là m.txt



cửa sổ sẽ là ^ M ^ J
barlop

3
"Tôi không thể nhập ^ M trên dòng lệnh bash". Có bạn có thể. Hãy thử control-V Control-M
Hennes

Câu trả lời:


91
grep -r $'\r' *

Sử dụng -rcho tìm kiếm đệ quy và $''thoát theo kiểu c trong Bash.

Hơn nữa, nếu bạn chắc chắn đó là tệp văn bản, thì nó sẽ an toàn để chạy

tr -d $'\r' < filename

để loại bỏ tất cả \rtrong một tập tin.

Nếu sử dụng GNU sed, -icó thể thực hiện chỉnh sửa tại chỗ, do đó bạn sẽ không cần phải viết lại:

sed $'s/\r//' -i filename

10
@Nicolas: Bạn có thể nhập ^ M tại dòng lệnh bằng cách nhấn ^ V ^ M, nhưng tốt hơn là sử dụng $'\r'.
Dennis Williamson

Tuyệt vời, nó hoạt động! Cảm ơn vì đã lừa ^ V ^ M :-)
Nicolas Raoul

5
Theo Cygwin, -U là cần thiết để thực hiện công việc này. Và -n sẽ cho bạn biết số dòng: grep -r -U -n -e $ '\ r'
Rainer Blome

4
Thêm một -l vào lệnh grep để chỉ xem tên tệp. Khác, bạn có thể bị bắn phá với các dòng phù hợp.
Brendan Byrd

1
@uprego không chắc bây giờ bạn có hiểu chúng không, nhưng fyi và những người khác, tìm kiếm $'đọc lần truy cập đầu tiên trong manpage bash(1), về cơ bản, bạn có thể thấy nó như thể bạn đang viết chuỗi chữ C. Đối với việc command < filenamesử dụng <hoặc >được gọi là chuyển hướng , đây là lần đầu tiên tôi thấy bất kỳ ai gọi đó là biểu hiện lớn hơn . Tìm kiếm REDIRECTIONtrong bash(1).
sống

12

Khi tôi thử, tôi có thể nói nó đang hoạt động, nhưng các dòng đang in trống. Thêm vào tùy chọn:

--color=never

Nếu bạn gặp phải vấn đề này, tôi nghĩ đó là các ký tự thoát để làm nổi bật màu sắc gây nhiễu cho \rnhân vật.


2

Nếu máy chủ của bạn không có bash shell, một giải pháp thay thế là sử dụng -ftùy chọn trên grep, kết hợp với tệp được chuẩn bị có chứa \r.

Để tạo tập tin:

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

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

Để thực sự tìm kiếm

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

hoặc bạn có thể lười biếng một chút và chỉ cần gõ *,

$ grep -f /tmp/cr *

Các tùy chọn trên được sử dụng để xác định một tập tin có chứa mẫu để phù hợp, mỗi dòng một. Trong trường hợp này chỉ có một mẫu.-f filenamegrep


2

Nếu tôi hiểu chính xác câu hỏi của bạn, điều bạn thực sự muốn là bình thường hóa tất cả các kết thúc dòng \x0atheo tiêu chuẩn Unix LF ( ). Điều đó không giống như việc loại bỏ CRs ( \x0d) một cách mù quáng .

Nếu bạn tình cờ có một số tệp Mac xung quanh chỉ sử dụng CR cho dòng mới, bạn sẽ hủy các tệp đó. (Có, máy Mac được cho là sử dụng LF từ gần 20 năm, nhưng vẫn còn (năm 2019) nhiều ứng dụng Mac chỉ sử dụng CR).

Bạn có thể sử dụng \R lối thoát dòng của Perl để thay thế bất kỳ loại dòng mới nào \n.

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

Điều này sẽ thay thế tại chỗ bất kỳ loại linebreak với \ntrong $your_file, giữ một bản sao lưu của tập tin gốc trong ${your_file}.bak.


1

Để sử dụng grep trên các ký tự cuối dòng, tôi đoán bạn phải nói với grep tệp là nhị phân.

-l (chữ L) chỉ để in tên tệp

-P dành cho perl regrec (vì vậy \ x0d được chuyển thành \ r hoặc ^ M)

grep -l --binary -P '\x0d' *

0

Nếu bạn đang dùng Mac và sử dụng homebrew , bạn có thể làm:

brew install tofrodos
fromdos file.txt

để loại bỏ tất cả các trả về vận chuyển Windows từ file.txt

Để quay trở lại vận chuyển Windows,

todos file.txt

để tìm kiếm trong một thư mục và xóa tất cả các tệp đến từ dos, hãy chạy lệnh này: find. -type f -name "* .java" | xargs fromdos
Taiko

0

Trong phong cách biểu thức chính quy, nhiều dòng mới:

Windows (CR LF)
\r\n

Unix (LF)
\n

\r\ntrình tự khá độc đáo, tôi nghĩ bạn có thể tìm kiếm theo cách đó không?

Để làm cho mọi thứ tồi tệ hơn, máy Mac đã từng sử dụng '\ r' thay cho dòng mới. Tôi không thể xác minh điều này, nhưng tôi không nghĩ rằng các thế hệ MacOSX làm điều đó nữa.

Máy Mac cũ (CR)
\r


Trong thư mục chứa m.txt, grep "\r\n" *không có kết quả. Không có kết quả nào cho egrep -e "\r\n" *cảgrep -E "\r\n" *
Nicolas Raoul

@nicolas ah, tôi hiểu nhầm .. ý bạn là CR chỉ \rxấu của tôi. Một dòng mới đầy đủ của windows thực sự là \r\nhoặc CRLF
Jeff Atwood

0

Theo dõi các câu trả lời trước, phương pháp 'tr' là tốt:

533 $ nếu [[-n " tr -cd "\r" <~/.bashrc"]]; sau đó lặp lại "DOS"; tiếng vang khác "UNIX"; fi

UNIX

534 $ nếu [[-n " tr -cd "\r" <dosfile.txt"]]; sau đó lặp lại "DOS"; tiếng vang khác "UNIX"; fi

DOS

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.