Cách tìm dòng bắt đầu bằng **


8

Tôi cần tìm nếu có bất kỳ dòng trong một tập tin bắt đầu với **.

Tôi không thể tìm ra cách để làm điều đó bởi vì *được hiểu là một ký tự đại diện bởi vỏ.

grep -i "^2" test.out

hoạt động nếu dòng bắt đầu bằng 2 nhưng

grep -i "^**" test.out 

rõ ràng là không hoạt động.

(Tôi cũng cần biết nếu dòng này kết thúc bằng một )nhưng chưa thử nó).

Câu trả lời:


18

Sử dụng \ký tự để thoát dấu * để biến nó thành một ký tự bình thường.

grep '^\*\*' test.out

Cũng lưu ý trích dẫn đơn 'và không trích dẫn kép "để ngăn chặn việc mở rộng vỏ


3
Cái đầu tiên *không cần thoát trong trường hợp cụ thể này, fwiw.
don_crissti

5
Mặc dù không cần phải thoát, nhưng không thoát khỏi dấu sao đầu tiên sẽ gây nhầm lẫn hơn từ một người quan sát thông thường, như thể bạn đang khớp "bất kỳ số lượng bắt đầu nào của dòng sau dấu hoa thị". Bất cứ điều gì làm cho một regrec trực quan hơn cho một người bảo trì là một ý tưởng tốt. =)
Trình biên dịch dễ thấy

1
Sử dụng dấu ngoặc kép cũng sẽ ngăn chặn việc mở rộng, không chỉ trích dẫn đơn. Lời khuyên sai ở đây.
rems4e

@ rems4e sử dụng dấu ngoặc kép sẽ ngăn vỏ mở rộng các dấu sao, nhưng không thể giải thích dấu gạch chéo ngược. Với dấu ngoặc kép, bạn phải sử dụng grep "^\\*\\*"để grep nhận được ^\*\*chuỗi cần tránh để diễn giải các dấu hoa thị dưới dạng định lượng regex.
Aaron

7

Khi bạn muốn kiểm tra dòng bắt đầu **và kết thúc bằng ), bạn có thể kết hợp hai grepthao tác như thế này,

grep '^*\*' test.out | grep ')$'

Hoặc với một greplệnh như thế này,

grep -E '^\*\*.*\)$' test.out

Giải trình

  • ^\*\* : dòng khớp bắt đầu bằng **
  • .* : khớp mọi thứ sau **
  • \)$: dòng khớp cũng có )ở cuối dòng.

3

Nó không phải là vỏ

Không có câu trả lời nào cho đến nay đã chạm vào vấn đề thực sự. Nó sẽ hữu ích để giải thích tại sao nó không hoạt động như bạn mong đợi.

grep -i "^**" test.out

Bởi vì bạn đã trích dẫn các mô hình để grep , *được không mở rộng bằng vỏ. Nó được truyền cho grep như vốn có. Điều này được giải thích trong trang hướng dẫn [1] cho bash [2] :

Việc đóng dấu các ký tự trong dấu ngoặc kép sẽ giữ giá trị bằng chữ của tất cả các ký tự trong dấu ngoặc kép, ngoại trừ $, `, \, và, khi mở rộng lịch sử được bật,!.

Đó là biểu thức chính quy thông thường

Biểu thức chính quy là một mẫu mô tả một chuỗi các chuỗi.

*là một trong những mẫu chính trong biểu thức chính quy. Theo mặc định, grep diễn giải nó như sau:

* The preceding item will be matched zero or more times.

Điều này có nghĩa là mô hình của bạn khi nó đứng, ^**không có nhiều ý nghĩa. Có thể nó cố gắng khớp với đầu của dòng 0 hoặc nhiều lần , hai lần. Dù điều đó có nghĩa là gì.

Giải pháp là trích dẫn nó:

Bất kỳ ký tự meta nào có ý nghĩa đặc biệt có thể được trích dẫn bằng cách đặt trước nó bằng dấu gạch chéo ngược.

grep -i "^\*\*" test.out


[1] Tôi không khuyên bạn nên đọc nó. Vui lòng sử dụng man dashhoặc tương tự thay thế.

[2] Không có vỏ được đưa ra, vì vậy tôi giả sử bash .


2

Sự lựa chọn khác.

Bạn có thể sử dụng sedhoặc awkcũng có thể

$ sed -n '/^*\*/p' test.out
$ awk '/^*\*/' test.out

Để biết các dòng kết thúc bằng )việc sử dụng cũng grephoặc sedhoặcawk

$ grep ')$' test.out
$ sed -n '/)$/p' test.out
$ awk '/)$/' test.out

Cảm ơn mọi người ! Tôi thực sự đánh giá cao sự giúp đỡ về điều này!
Shar Hunter

1
Và dòng awk kết hợp: '/^*\*/&&/)$/'...
jasonwryan

0

Đây là phiên bản hoàn toàn không được trích dẫn : grep ^\\*\\* test.out. Để chuyển một dấu gạch chéo ngược từ vỏ sang grep, nó cần phải được thoát.

Điều này hoạt động miễn là bạn không có tệp nào trong thư mục bắt đầu bằng ^\và chứa một dấu gạch chéo ngược khác.

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.