Biểu thức chính quy để tìm các ký tự kép trong Bash


10

Tôi đang tìm một biểu thức chính quy tìm thấy tất cả các lần xuất hiện của các ký tự kép trong một văn bản, một danh sách, v.v. trên dòng lệnh (Bash).

Câu hỏi chính : Có một cách đơn giản để nhìn cho chuỗi như aa, ll, tttttvv nơi người ta định nghĩa một biểu thức chính quy mà vẻ bề ngoài cho n lần xuất hiện của nhân vật cùng với ai? Những gì tôi đang tìm kiếm là đạt được điều này ở mức độ rất cơ bản. Trên dòng lệnh. Trong một vỏ Linux.

Sau một vài nghiên cứu, tôi đã đi đến những câu trả lời sau - và những câu hỏi phát sinh từ chúng, do đó họ chỉ cho tôi một gợi ý về giải pháp có thể là gì. Nhưng:

a) (e) grep và vấn đề dấu gạch chéo ngược

  • grep 'a\{2\}' tìm kiếm aa
  • egrep'a{2}' tìm kiếm aa

Câu hỏi: Sự cần thiết phải thiết lập các phản ứng ngược có thực sự ràng buộc với lệnh tôi sử dụng không? Nếu vậy, bất cứ ai cũng có thể cho tôi gợi ý những gì khác cần được tính đến khi sử dụng (e) grep ở đây?

b) Tôi đã tìm thấy câu trả lời này ở đây cho câu hỏi của mình, mặc dù đó không phải là chính xác những gì tôi đang tìm kiếm:

grep -E '(.)\1' filenametìm kiếm các mục có cùng ký tự xuất hiện nhiều lần nhưng không hỏi tần suất . Điều này gần với những gì tôi đang tìm kiếm, nhưng tôi vẫn muốn thiết lập một số lần lặp lại.

Tôi có lẽ nên chia câu hỏi này thành hai hoặc nhiều câu hỏi, nhưng sau đó tôi không muốn tràn ngập trang web tuyệt vời này ở đây.

PS: Một câu hỏi, có thể off topic nhưng: là nó in, inside, athoặc on the shell. Và có on the command lineđúng không?

Câu trả lời:


8

Đây thực sự là hai câu hỏi, và nên được chia ra. Nhưng vì các câu trả lời tương đối đơn giản, tôi sẽ đặt chúng ở đây. Những câu trả lời này dành cho GNU grep.

a) egrepgiống như grep -E. Cả hai đều chỉ ra rằng "Biểu thức chính quy mở rộng" nên được sử dụng thay cho grepBiểu thức chính quy mặc định. grepyêu cầu dấu gạch chéo ngược cho Biểu thức chính quy đơn giản.

Từ mantrang:

Biểu thức cơ bản và mở rộng

Trong các biểu thức chính quy cơ bản các siêu ký tự ? , + , { , | , () mất đi ý nghĩa đặc biệt của chúng; thay vì sử dụng các phiên bản gạch chéo ngược \? , \ + , \ { , \ | , \ (\) .

Xem mantrang để biết thêm chi tiết về các quy ước lịch sử và tính di động.

b) Sử dụng egrep '(.)\1{N}'và thay thế Nbằng số lượng ký tự bạn muốn thay thế trừ đi một ký tự (vì dấu chấm khớp với ký tự đầu tiên). Vì vậy, nếu bạn muốn khớp một nhân vật được lặp lại bốn lần, hãy sử dụng egrep '(.)\1{3}'.


Khi đọc trang người đàn ông tôi phải thực sự hiểu sai hoặc hiểu sai phần bạn đã chỉ. Khi tôi làm việc thông qua một số hướng dẫn biểu thức chính quy, không có gợi ý nào về hành vi như vậy được mong đợi. Tôi nghĩ rằng Biểu thức chính quy có nghĩa là một cái gì đó ở mức cơ bản đến mức hầu hết các ứng dụng đang hoạt động với cùng một bộ ký hiệu. Một lần nữa, tôi đã được chứng minh là sai. Cảm ơn bạn đã giúp đỡ! Điều này thực sự giúp tôi ra ngoài.
erch

Việc đọc cũng khá khó hiểu " luôn luôn sử dụng dấu gạch chéo ngược để lấy ý nghĩa đặc biệt từ các ký tự như., +, V.v. " và sau đó phát hiện ra rằng dường như ngược lại là quy tắc với lệnh cơ bản nhất.
erch

@ cellar.dweller Thật khó hiểu! Rất nhiều lý luận là lịch sử. Tôi quen thuộc hơn với biểu mẫu Mở rộng, vì vậy tôi tạo thói quen luôn chỉ sử dụng egrepnếu tôi cần các biểu thức chính quy (trái ngược với chỉ khớp chuỗi đơn giản) để tôi không phải lo lắng về việc nhớ các khác biệt giữa grephai các loại biểu thức chính quy.
depquid

4
Lưu ý rằng ERE tiêu chuẩn không hỗ trợ tham chiếu ngược, trong khi BRE tiêu chuẩn thì có. Vậy grep '\(.\)\1\{3\}'là chuẩn, grep -E '(.)\1{3}'không phải.
Stéphane Chazelas

7

Điều này sẽ tìm kiếm 2 hoặc nhiều lần xuất hiện của cùng một nhân vật:

grep -E '(.)\1+' file

Nếu awk của bạn có tùy chọn -o, điều này sẽ in mỗi trận đấu trên một dòng mới ..

grep -Eo '(.)\1+' file

Để tìm trận đấu có đúng 3 trận đấu:

grep -E '(.)\1{2}' file

Hoặc 3 hoặc nhiều hơn:

grep -E '(.)\1{2,}' file

Vân vân..


biên tập

Trên thực tế @stephane_chazelas nói đúng về các tài liệu tham khảo và -E. Tôi đã quên về điều đó. Tôi đã thử nó trong BSD grep và GNU grep và nó hoạt động ở đó nhưng nó không có trong một số greps khác. Bạn sẽ cần sử dụng một trong những phiên bản dưới đây ..

Phiên bản grep thông thường:

grep '\(.\)\1\{1,\}' file

grep -o '\(.\)\1\{1,\}' file

grep '\(.\)\1\{2\}' file

grep '\(.\)\1\{2,\}' file

Các -otùy chọn cũng không phải là tiêu chuẩn grep BTW (có lẽ nếu grep bạn hiểu -o nó cũng có thể làm tài liệu tham khảo sau) ..


Lưu ý : grep -E '(.)\1{2,}'tập tin và grep '\(.\)\1\{2\}'tập tin sai như alexis đã chỉ ra và nên bỏ qua ..


Cảm ơn bạn, cho đến nay. Nhưng: Tôi có đúng không khi nói rằng không có -Etùy chọn grepsẽ không làm được gì nhiều? Điều này sẽ giải thích khá nhiều, ví dụ tại sao tôi lãng phí quá nhiều thời gian để tìm kiếm nơi tôi đã sai!
erch

Nếu không có tùy chọn -E, bạn có thể làm tương tự trong trường hợp này, nhưng bạn sẽ cần phải thoát nhiều hơn và không có +toán tử .. Tôi cũng sẽ đăng ví dụ.
Scrutinizer

Một điều chỉnh nhỏ: grep -E '(.)\1{2}'không chính xác "Tìm kết quả khớp với đúng 3 kết quả". Mặc dù nó sẽ khớp chính xác ba ký tự giống hệt nhau, nhưng chúng có thể được nhúng trong một chuỗi lặp lại dài hơn; ví dụ, nó sẽ khớp trong chuỗi 5 ký hiệu AAAAA. (Và nếu có 6 biểu tượng liên tiếp trở lên, nó sẽ khớp nhiều lần).
alexis

Có bạn hoàn toàn đúng, điều đó không hoạt động như dự định, thực tế là không thể như vậy ..
Scrutinizer

3

Trước tiên, cảm ơn tất cả các ý kiến ​​và đề xuất hỗ trợ của bạn. Hóa ra tôi đã khá gần với câu trả lời.

Các vấn đề chính là về:

Có một cách đơn giản để tìm kiếm n lần xuất hiện của nhân vật tương tự, ví dụ như aa,tttttt

Câu trả lời ngắn gọn :

Các lệnh [biến thể] sau đây sẽ lặp lại aít nhất một và vô số lần

grep 'a\{1,}

grep -E \(a\)\{1,\}

egrep a{1,}

hoặc, với biểu thức chính quy GNU có sẵn grep a\+


Số lần lặp lại được đặt bên trong dấu ngoặc nhọn, thông qua mẫu {min,max}{n}lặp lại chính xác nthời gian, {n,}lặp lại ít nhất nlần và {n,m}lặp lại ít nhất nnhưng ít nhất là nhiều mlần.

Do đó, như một hệ quả, đã đưa ra vấn đề thứ yếu :

Là sự cần thiết của thiết lập backlash ràng buộc với lệnh tôi sử dụng?

Câu trả lời ngắn : Có, việc sử dụng dấu gạch chéo ngược phụ thuộc vào việc người ta sử dụng grephayegrep

  • grep: dấu gạch chéo ngược kích hoạt siêu ký tự [sử dụng Biểu thức chính quy cơ bản]
  • egrepdấu gạch chéo ngược khử các ký tự đại diện [sử dụng biểu thức chính quy mở rộng]

Vì đây là câu trả lời ngắn, tôi muốn cung cấp cho những người gặp phải các vấn đề tương đương, tôi đã thêm vào bản tóm tắt cơ bản của tôi về những gì mà một người dường như phải nhận thức được, làm việc với grepegrep.




Biểu thức cơ bản, mở rộng và GNU

Biểu thức chính quy cơ bản

Được sử dụng trong grep, edsedlệnh

Các tính năng thiết lập Biểu thức chính quy cơ bản là:

  • Hầu hết các Metachar character, ? [ . \ )v.v. được kích hoạt thông qua dấu gạch chéo ngược. Nếu không có dấu gạch chéo ngược, chúng sẽ được coi là (một phần của) cụm từ tìm kiếm.
  • ^ $ \<\>được hỗ trợ mà không có dấu gạch chéo ngược
  • Không có ký tự viết tắt [ \b, \svv]

GNU Basic Expressions thêm vào những

  • \?lặp lại ký tự 0 hoặc một lần ( c\?khớp ccc) và là một thay thế cho\{0,1\}
  • \+lặp lại một ký tự ít nhất một lần ( c\+khớp cc, ccccccccv.v.) và là một thay thế cho\{1,\}

  • \|được hỗ trợ (ví dụ: grep a\|bsẽ tìm ahoặcb

grep -E cho phép lệnh sử dụng toàn bộ tập hợp Biểu thức chính quy mở rộng:


Biểu thức chính quy mở rộng [ERE]

Được sử dụng trong egrep, awkemacslà Set cơ bản cộng với một số tính năng khá.

  • Siêu nhân vật bị vô hiệu hóa thông qua dấu gạch chéo ngược
  • Không có tài liệu tham khảo trở lại
  • khác: rất nhiều phép thuật Biểu thức chính quy thường có thể làm cho một

GNU Extendend Biểu thức chính quy

thêm các tính năng sau

Hai liên kết sẽ hướng một đến thường xuyên.expressions.info, ngoài sự hỗ trợ tuyệt vời mà tôi có ở đây, thực sự đã giúp tôi rất nhiều.

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.