2008-09-16 32 views
94

Tôi muốn tìm kiếm các tệp có chứa kết thúc dòng dos với grep trên Linux. Một cái gì đó như thế này:Làm thế nào để bạn tìm kiếm các tệp có chứa kết thúc dòng dos (CRLF) với grep trên Linux?

grep -IUr --color '\r\n' . 

Ở trên dường như phù hợp với chữ rn không phải là điều mong muốn.

Kết quả của điều này sẽ được đường ống thông qua xargs vào todos để chuyển đổi CRLF TĐT như thế này

grep -IUrl --color '^M' . | xargs -ifile fromdos 'file' 
+0

Bạn đã thử [dos2unix] (http://linux.die.net/man/1/dos2unix) chưa? Nó tự động sửa kết thúc dòng. – sblundy

+0

Tôi không hoàn toàn chắc chắn nhưng iirc có một sự khác biệt giữa trích dẫn các mẫu bên trong 'và'. Afaik trong các mẫu kèm theo trong 'chuỗi thoát được hiểu là chuỗi thích hợp để' \ r 'sẽ tương đương với "\\ r" và "\ r" không tương đương (ít nhất là trong ký hiệu đó) với '. – Anticom

+0

Anticom: Bạn đúng trong trường hợp này là sự khác biệt giữa' và 'không liên quan; tuy nhiên, nói chung chúng khác biệt với nhau khi các chuỗi được bao quanh bị trích dẫn yếu và “được trích dẫn mạnh mẽ. Điều lớn nhất tôi tận dụng là mở rộng $ hay' 'không mở rộng trong các chuỗi trích dẫn yếu. ] (http://wiki.bash-hackers.org/syntax/quoting) để biết thêm chi tiết – bschlueter

Trả lời

88

Sử dụng Ctrl + V, Ctrl + M nhập Vận chuyển đen Trả về ký tự trong chuỗi grep của bạn. Vì vậy:

grep -IUr --color "^M" 

sẽ hoạt động - nếu có một chữ CR mà bạn nhập như tôi gợi ý.

Nếu bạn muốn danh sách tệp, bạn cũng muốn thêm tùy chọn -l.

Giải thích

  • -I bỏ qua tập tin nhị phân
  • -U ngăn grep dải ký tự CR. Theo mặc định nó sẽ làm điều đó nếu nó quyết định đó là một tập tin văn bản.
  • -r đọc tất cả các tệp theo từng thư mục một cách đệ quy.
+3

Như là một hack nhanh chóng mà sẽ làm việc nhưng tôi nghĩ rằng giải pháp readbale của con người sẽ là: grep $ '\ r'/bash shell chỉ/hoặc grep 'printf '\ r'' – akostadinov

+3

@akostadinov +1, Nhưng backticks đã giải thích ra khỏi của bạn bình luận;) Tùy chọn thứ hai, nói cách khác, là ** 'grep $ (printf '\ r')' **. Nhưng đối với hầu hết các ứng dụng thực tế liên quan đến bash, tôi sẽ gắn bó với '$ '\ r''. – jankes

+3

Lưu ý: Tùy chọn '-U' chỉ phù hợp với Windows (hoặc Cygwin), nhưng nó rất quan trọng ở đó. Trên Windows, lệnh sẽ không hoạt động nếu không có nó. – sleske

119

grep có lẽ không phải là công cụ bạn muốn cho việc này. Nó sẽ in một dòng cho mỗi dòng phù hợp trong mỗi tập tin. Trừ khi bạn muốn, nói, chạy todos 10 lần trên một tập tin 10 dòng, grep không phải là cách tốt nhất để đi về nó. Sử dụng find để chạy tập tin trên tất cả các tập tin trong cây sau đó grepping qua đó cho "CRLF" sẽ giúp bạn có một dòng đầu ra cho mỗi tập tin trong đó có dos phong cách kết thúc dòng:

find . -not -type d -exec file "{}" ";" | grep CRLF

sẽ giúp bạn có một cái gì đó như:

./1/dos1.txt: ASCII text, with CRLF line terminators 
./2/dos2.txt: ASCII text, with CRLF line terminators 
./dos.txt: ASCII text, with CRLF line terminators
+0

Tôi đã bẻ khóa này, nhưng dù sao cũng được. 'grep -IUrl --color '^ M'. | xargs -ifile fromdos 'file'' –

+4

Tùy chọn -l để grep yêu cầu nó chỉ liệt kê các tệp (một lần) thay vì liệt kê các kết quả phù hợp trong mỗi tệp. – pjz

+4

Không phải là một giải pháp tốt, phụ thuộc vào hành vi đó (không có giấy tờ, hướng tới tiêu thụ con người) của chương trình 'tệp'. Điều này rất mong manh. Đối với (chỉ một) ví dụ: nó không hoạt động với các tệp XML, 'tệp' báo cáo' văn bản tài liệu XML' bất kể loại dòng mới. – leonbloy

14

Nếu phiên bản của grep hỗ trợ -P (--perl-regexp) tùy chọn, sau đó

grep -lUP '\r$' 

có thể được sử dụng.

6
# list files containing dos line endings (CRLF) 

cr="$(printf "\r")" # alternative to ctrl-V ctrl-M 

grep -Ilsr "${cr}$" . 

grep -Ilsr $'\r$' . # yet another & even shorter alternative 
2

Truy vấn là tìm kiếm ... Tôi có một vấn đề tương tự ... ai đó gửi đường hỗn hợp kết thúc vào kiểm soát phiên bản, vì vậy bây giờ chúng tôi có một loạt các file với 0x0d 0x0d0x0a kết thúc dòng.Lưu ý rằng

grep -P '\x0d\x0a' 

tìm thấy tất cả các dòng, trong khi

grep -P '\x0d\x0d\x0a' 

grep -P '\x0d\x0d' 

thấy không có dòng nên có thể có một cái gì đó "khác" xảy ra bên trong grep khi nói đến xếp hàng mẫu kết thúc ... thật không may cho tôi!

1

Nếu, như tôi, unix tối giản của bạn không bao gồm niceties như tập tin lệnh, và những dấu xồ nguợc trong grep bạn biểu chỉ không hợp tác, cố gắng này:

$ for file in `find . -type f` ; do 
> dump $file | cut -c9-50 | egrep -m1 -q ' 0d| 0d' 
> if [ $? -eq 0 ] ; then echo $file ; fi 
> done 

Modifications bạn có thể muốn làm việc trên bao gồm:

  • chỉnh tìm lệnh để xác định vị trí chỉ các tập tin bạn muốn quét
  • thay đổi các tiện ích bãi lệnh để od hoặc bất cứ tập tin dump bạn có
  • xác nhận rằng cắt lệnh bao gồm cả một hàng đầu và đuôi không gian cũng như chỉ ra nhân vật thập lục phân từ bãi tiện ích
  • hạn chế bãi sản lượng đến 1.000 ký tự đầu tiên hoặc lâu hơn cho hiệu quả

Ví dụ, một cái gì đó như thế này có thể làm việc cho bạn sử dụng od thay vì đổ:

od -t x2 -N 1000 $file | cut -c8- | egrep -m1 -q ' 0d| 0d|0d$' 
38
+1

Vai trò của $ ở đây là gì? Nó hoạt động, nhưng làm thế nào? –

+3

http://linux.die.net/Bash-Beginners-Guide/sect_03_03.html –

+6

Cảm ơn! Để rõ ràng của những người đến sau, bash hướng dẫn sử dụng nói "Từ của hình thức $ 'chuỗi' được điều trị đặc biệt. Từ này mở rộng đến chuỗi, với ký tự thoát dấu gạch chéo thay thế theo quy định của tiêu chuẩn ANSI C." (xem thêm [danh sách các mã được hỗ trợ này] (http://www.gnu.org/software/bash/manual/bashref.html#ANSI_002dC-Quoting)) –

1

Bạn có thể sử dụng lệnh tập tin trong unix. Nó cung cấp cho bạn mã hóa ký tự của tệp cùng với các thuật ngữ dòng.

$ file myfile 
myfile: ISO-8859 text, with CRLF line terminators 
$ file myfile | grep -ow CRLF 
CRLF 
Các vấn đề liên quan