Tôi đã cố gắng tìm cách lọc một dòng có chữ "chanh" và "gạo" trong đó. Tôi biết cách tìm "chanh" hoặc "gạo" nhưng không phải hai người họ. Họ không cần phải ở bên cạnh người khác, chỉ cần một dòng văn bản giống nhau.
Tôi đã cố gắng tìm cách lọc một dòng có chữ "chanh" và "gạo" trong đó. Tôi biết cách tìm "chanh" hoặc "gạo" nhưng không phải hai người họ. Họ không cần phải ở bên cạnh người khác, chỉ cần một dòng văn bản giống nhau.
Câu trả lời:
"Cả hai trên cùng một dòng" có nghĩa là "'cơm" theo sau là các ký tự ngẫu nhiên theo sau là' chanh 'hoặc ngược lại ".
Trong regex đó là rice.*lemon
hoặc lemon.*rice
. Bạn có thể kết hợp điều đó bằng cách sử dụng |
:
grep -E 'rice.*lemon|lemon.*rice' some_file
Nếu bạn muốn sử dụng regex bình thường thay vì mở rộng ( -E
), bạn cần dấu gạch chéo ngược trước |
:
grep 'rice.*lemon\|lemon.*rice' some_file
Ví dụ, đối với nhiều từ nhanh hơn một chút và thường dễ sử dụng nhiều cuộc gọi hơn grep
:
grep rice some_file | grep lemon | grep chicken
grep rice
dòng tìm thấy có chứa rice
. Nó được đưa vào grep lemon
trong đó sẽ chỉ tìm thấy các dòng có chứa chanh .. và như vậy. Trong khi OP - cũng như các câu trả lời trước của bạn - đang cho phép bất kỳ [cơm | chanh | gà]
|
cần phải trốn thoát grep
? Cảm ơn!
egrep
sử dụng regex mở rộng trong đó |
được hiểu là logic OR. grep
mặc định cho regex cơ bản, ở đâu \|
HOẶC
grep
trang của, egrep
không được dùng nữa và nên được thay thế bằng grep -E
. Tôi lấy tự do để chỉnh sửa câu trả lời cho phù hợp.
Bạn có thể chuyển đầu ra của lệnh grep đầu tiên sang một lệnh grep khác và nó sẽ khớp với cả hai mẫu. Vì vậy, bạn có thể làm một cái gì đó như:
grep <first_pattern> <file_name> | grep <second_pattern>
hoặc là,
cat <file_name> | grep <first_pattern> | grep <second_pattern>
Hãy thêm một số nội dung vào tập tin của chúng tôi:
$ echo "This line contains lemon." > test_grep.txt
$ echo "This line contains rice." >> test_grep.txt
$ echo "This line contains both lemon and rice." >> test_grep.txt
$ echo "This line doesn't contain any of them." >> test_grep.txt
$ echo "This line also contains both rice and lemon." >> test_grep.txt
Tệp này chứa gì:
$ cat test_grep.txt
This line contains lemon.
This line contains rice.
This line contains both lemon and rice.
This line doesn't contain any of them.
This line also contains both rice and lemon.
Bây giờ, hãy grep những gì chúng ta muốn:
$ grep rice test_grep.txt | grep lemon
This line contains both lemon and rice.
This line also contains both rice and lemon.
Chúng tôi chỉ nhận được các dòng mà cả hai mẫu phù hợp. Bạn có thể mở rộng điều này và chuyển đầu ra sang một lệnh grep khác để khớp "VÀ" hơn nữa.
grep với tùy chọn -P
(Tương thích Perl) và biểu thức chính diện tích cực(?=(regex))
:
grep -P '(?=.*?lemon)(?=.*?rice)' infile
hoặc bạn có thể sử dụng dưới đây, thay vào đó:
grep -P '(?=.*?rice)(?=.*?lemon)' infile
.*?
phương tiện phù hợp với bất kỳ ký tự .
nào xuất hiện 0 hoặc nhiều lần *
trong khi chúng là tùy chọn theo sau bởi một mẫu ( rice
hoặc lemon
). Điều này ?
làm cho mọi thứ tùy chọn trước nó (có nghĩa là không hoặc một lần mọi thứ khớp với nhau .*
)(?=pattern)
: Cái nhìn tích cực: Cấu trúc của cái nhìn tích cực là một cặp dấu ngoặc đơn, với dấu ngoặc đơn mở đầu theo sau là một dấu hỏi và dấu bằng.
Vì vậy, điều này sẽ trả về tất cả các dòng có chứa cả hai lemon
và rice
theo thứ tự ngẫu nhiên. Ngoài ra, điều này sẽ tránh sử dụng |
s và nhân đôi grep
.
Liên kết ngoài:
Chủ đề Grep nâng cao Nhìn tích cực - GREP dành cho nhà thiết kế
Nếu chúng tôi thừa nhận rằng việc cung cấp một câu trả lời không grep
dựa trên là có thể chấp nhận được, như câu trả lời trên dựa trên awk
, tôi sẽ đề xuất một perl
dòng đơn giản như:
$ perl -ne 'print if /lemon/ and /rice/' my_text_file
Việc tìm kiếm có thể bỏ qua trường hợp với một số / tất cả các từ như /lemon/i and /rice/i
. Trên hầu hết các máy Unix / Linux, perl được cài đặt cũng như awk.
Đây là một kịch bản để tự động hóa giải pháp đường ống grep:
#!/bin/bash
# Use filename if provided as environment variable, or "foo" as default
filename=${filename-foo}
grepand () {
# disable word splitting and globbing
IFS=
set -f
if [[ -n $1 ]]
then
grep -i "$1" ${filename} | filename="" grepand "${@:2}"
else
# If there are no arguments, assume last command in pipe and print everything
cat
fi
}
grepand "$@"
eval
ing nó, nó dễ dàng bị phá vỡ