Kết hợp chuỗi với một số ký tự cố định bằng grep


9

Tôi đang cố gắng tìm tất cả các 6từ thư bằng cách sử dụng grep. Tôi hiện đang có điều này:

grep "^.\{6\}$" myfile.txt 

Tuy nhiên, tôi thấy rằng tôi cũng đang nhận được kết quả như: étuis, étude.

Tôi nghi ngờ nó có một cái gì đó làm với các biểu tượng ở trên etrong các từ trên.

Có điều gì tôi có thể làm để đảm bảo rằng điều này không xảy ra?

Cảm ơn bạn đã giúp đỡ!

Câu trả lời:


4

grepÝ tưởng của một nhân vật phụ thuộc vào địa phương . Nếu bạn đang ở một địa điểm không phải là Unicode và bạn grep từ một tệp có các ký tự Unicode trong đó thì số ký tự sẽ không khớp. Nếu echo $LANGsau đó bạn sẽ thấy miền địa phương bạn đang ở.

Nếu bạn đặt biến LC_CTYPEvà / hoặc LANGbiến môi trường thành giá trị kết thúc bằng ".UTF-8" thì bạn sẽ có hành vi đúng:

$ cat data
étuis
letter
éééééé
$ LANG=C grep -E '^.{6}$' data
étuis
letter
$ LANG=en_US.UTF_8 grep -E '^.{6}$' data
letter
éééééé
$

Bạn có thể thay đổi ngôn ngữ của mình chỉ bằng một lệnh bằng cách gán biến trên cùng dòng với lệnh.

Với cấu hình này, các ký tự nhiều byte được coi là các ký tự đơn. Nếu bạn muốn loại trừ hoàn toàn các ký tự không phải ASCII, một số câu trả lời khác có giải pháp cho bạn.


Lưu ý rằng mọi thứ vẫn có thể bị phá vỡ, hoặc ít nhất là không làm chính xác những gì bạn mong đợi, với sự có mặt của các nhân vật kết hợp . Bạn grepcó thể đối xử với LATIN SMALL LETTER E + COMBINING CHARACTER ACUTE TRÊN khác với LATIN SMALL LETTER E VỚI ACUTE.


nếu bạn sử dụng ., một cái gì đó giống như wăsd'ssẽ khớp
cuonglm

'là một ký tự hợp lý có thể là một phần của "chuỗi có số ký tự cố định".
Michael Homer

Có lẽ. Và bạn nên đặt cả hai LC_CTYPELANG, một cái gì đó như LC_CTYPE=en_US.UTF-8 LANG=en_USsẽ thất bại. Sử dụng LC_ALLcho an toàn.
cuonglm

2

Thử cái này:

LC_ALL=C.UTF-8 grep -x '[_[:alnum:]]\{6\}' file

-xsử dụng để khớp toàn bộ dòng và được xác định bởi POSIX (Xem grep ).

Xem ở đây để giải thích tốt về những gì LC_ALLkhông. Bạn có thể đặt LANGhoặc LC_CTYPEsử dụng utf-8 để có hành vi tương tự. Thứ tự ảnh hưởng là LC_ALL=> LANG=> LC_CTYPE.


2

Với GNU grepkhi được xây dựng với sự hỗ trợ của PCRE, bạn có thể làm:

grep -Px '\X{6}'

Trong khi .khớp với một ký tự, \Xkhớp với một biểu tượng / đồ thị.

Trong ngôn ngữ UTF-8:

$ locale charmap
UTF-8
$ printf '\u00e9tuis\n\u00e9tudes\n' | grep -Px '\X{6}'
études
$ printf 'e\u0301tuis\ne\u0301tudes\n' | grep -Px '\X{6}'
études

Trong đó études, có 7 ký tự, 8 byte và 6 biểu đồ.


Có vẻ như nó không hoạt động: echo épée | grep -Px '\X{6}'ouputépée
cuonglm

@Gnouc, bạn cần chạy nó trong miền địa phương UTF-8 (nếu những thứ éở trên được mã hóa theo UTF-8).
Stéphane Chazelas

Ôi, những sai lầm của tôi. Nó hoạt động với UTF-8.
cuonglm

0

Bạn có thể thử một cái gì đó như:

grep "^[A-Za-z]\{6\}$" myfile.txt

hoặc nếu các từ cũng có thể chứa số, thì:

grep "^[A-Za-z0-9]\{6\}$" myfile.txt

Chỉ cần thêm bất kỳ ký tự nào vào dấu ngoặc vuông mà bạn muốn thêm vào đó.


Điều này sẽ không phù hợp étudevới tất cả, bởi vì ký tự ASCII tương ứng với dấu sẽ làm rối loạn biểu thức chính quy.
Alex
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.