Một công cụ rất hữu ích để gỡ lỗi loại điều này là od
. Truyền đầu ra của grep
lệnh thông qua od
cho thấy tệp của bạn chứa các kết thúc dòng kiểu DOS, return return ( \r
) theo sau là một dòng mới ( \n
):
$ grep -i '."spacer">.' default.php | od -c
0000000 \t \t \t \t \t < d i v c l a s s =
0000020 " s p a c e r " > \r \n \t \t \t < d
0000040 i v c l a s s = " s p a c e r
0000060 " > \r \n
0000064
Vì vậy, để kiểm tra, tôi đã tạo tệp thử nghiệm tối thiểu này:
$ echo -ne "<div class=\"spacer\">\r\n<div class=\"spacer\">\r\n" > foo.php
$ cat foo.php
<div class="spacer">
<div class="spacer">
Tôi xác nhận rằng grep
in các dòng trống:
$ grep -i '."spacer">.' foo.php
$
Các lý do nó được in dòng sản phẩm nào là sự trở lại vận chuyển ( \r
). Bạn đang yêu cầu grep
tìm chuỗi spacer">
và ký tự sau . Trong tập tin của bạn, ký tự sau đây là \r
. In \r
trong thiết bị đầu cuối có tác dụng xóa dòng cuối cùng được in để nó hiển thị một dòng trống. Bạn có thể kiểm tra điều này bằng lệnh sau:
$ echo -e "foo\rbar"
bar
Điều thực sự xảy ra là đầu tiên foo
được in, sau đó bị xóa vì \r
và được thay thế bởi bar
. Kiểm tra với od
:
$ echo -e "foo\rbar" | od -c
0000000 f o o \r b a r \n
0000010
Bây giờ, tôi không hiểu tại sao colors
tùy chọn grep
thay đổi mọi thứ. Nó phải có một cái gì đó để làm với cách hiển thị các ký tự đặc biệt. Trong mọi trường hợp, bạn có thể khắc phục sự cố của mình bằng cách xóa tất cả \r
:
$ sed 's/\r//g' default.php > bar.php
Sau đó, xóa cái cuối cùng .
khỏi mẫu grep của bạn (hãy nhớ rằng theo mặc định .
không khớp với dòng mới mặc dù nó không khớp \r
):
$ grep -ni '."spacer">' bar.php
103: <div class="spacer">
222: <div class="spacer">