Tệp bạn đã hiển thị có tất cả các chi tiết trên một dòng:
name : farah age : 23 phone number : 0123 education : degree
Tôi đã giả sử rằng bạn có thể mã cứng age :
vv vào lệnh, nhưng văn bản theo sau nó sẽ thay đổi và các chi tiết có thể không theo thứ tự nhất định hoặc không liền kề.
Bạn có thể trích xuất các bộ phận của phù hợp với grep
's -o
cờ. Điều này chỉ in phần phù hợp, chứ không phải toàn bộ dòng.
Nếu bạn muốn bao gồm các phần age :
và phone number :
phần, bạn có thể sử dụng -e
cờ để chỉ định nhiều kết quả khớp hoặc xen kẽ.
$ grep -oe 'age : [^ ]*' -e 'phone number : [^ ]*' file
age : 23
phone number : 0123
Biểu thức [^ ]*
có nghĩa là bất kỳ số lượng ký tự không phải là khoảng trắng, do đó, nó khớp với các ký tự sau age :
đến không gian tiếp theo.
Thay thế file
bằng tên của tệp có chứa thông tin của bạn. Bạn có thể viết tệp mới bằng cách chuyển hướng đầu ra sang tệp mới với >
toán tử, như sau:
grep -oe 'age : [^ ]*' -e 'phone number : [^ ]*' file > outfile
Khi bạn làm điều đó, bạn sẽ không thấy bất kỳ đầu ra. Bạn nên kiểm tra đầu ra trước, sau đó thêm chuyển hướng.
Đây là ví dụ với sự xen kẽ. Chúng tôi sử dụng -E
cờ để nói grep
để sử dụng regex mở rộng. Cú pháp là (pattern1|pattern2)
- điều này khớp pattern1
và / hoặc pattern2
. Nếu một trong hai được tìm thấy, nó sẽ được in (bất kể người khác có tìm thấy hay không). Bây giờ tôi đang sử dụng +
ý nghĩa ít nhất một trong các ký tự trước, thay vì *
có nghĩa bằng 0 hoặc nhiều hơn ký tự trước. Trong bối cảnh này, cả hai đều hoạt động tốt như nhau.
$ grep -Eo '(age : [^ ]+|phone number : [^ ]+)' file
age : 23
phone number : 0123
Nếu bạn muốn bỏ qua các phần age :
và phone number:
phần, bạn có thể sử dụng -P
cờ để yêu cầu grep
sử dụng các biểu thức chính quy tương thích Perl. Điều này hỗ trợ xen kẽ và cũng là một cách khớp văn bản sau một mẫu nhất định:
$ grep -Po '(age : \K[^ ]+|phone number : \K[^ ]+)' file
23
0123
Nếu bạn muốn định dạng văn bản khác nhau, bạn có thể sử dụng sed
, ví dụ:
$ sed -r 's/.*(age) : ([^ ]*).*(phone number) : ([^ ]*).*/\1:\2 | \3:\4/' file
age:23 | phone number:0123
Điều này phụ thuộc vào việc age
đến trước phone number
, vì vậy điều chỉnh cho phù hợp nếu đó không phải là trường hợp. Nếu bạn không thể dựa vào thứ tự, bạn có thể sử dụng lệnh rất phức tạp này:
$ sed -r 's/(.*)(phone number : [^ ]+)(.*) .*/\2 \1\4/; s/(phone number) : ([^ ]+) .*(age) : ([^ ]+).*/\1: \2 | \3: \4/' file
phone number: 0123 | age: 23
Điều này sắp xếp lại dòng để phone number :
phần đến trước trên mỗi dòng, sau đó thực hiện thay thế thứ hai để chọn các chi tiết mong muốn. Tôi nợ kỹ thuật được sử dụng ở đây cho câu trả lời này của muru .
Ghi chú về sed
các lệnh không được giải thích trước đây
-r
sử dụng regex mở rộng cho các lệnh dễ đọc hơn (GNU sed
hiểu -E
với cùng nghĩa)
s/old/new/
thay thế old
bằngnew
(pattern)
lưu pattern
vào tham chiếu sau, với \1
hoặc \2
vv (tương ứng với thứ tự từ trái sang phải trong đó các nhóm chụp xảy ra - lưu ý rằng sed
sẽ chỉ giữ tối đa 7 trong số này!).
.
bất kỳ ký tự nào, do đó .*
đại diện cho bất kỳ số lượng của bất kỳ ký tự.
;
tách các lệnh, như trong shell.