Câu trả lời:
awk có thể là một công cụ tốt hơn ở đây.
$ cat test.dat
LINE 1
LINE 2
POP3_SERVER_NAME = localhost
Tìm kiếm các dòng có chứa "POP3_SERVER_NAME"; in trường cuối cùng. Điều này không phụ thuộc vào POP3_SERVER_NAME luôn nằm trên dòng 3, đây có lẽ là một điều tốt.
$ awk '/POP3_SERVER_NAME/{print $NF}' test.dat
localhost
Tùy thuộc vào ứng dụng của bạn, bạn có thể cần phải thực hiện biểu thức chính quy nghiêm ngặt hơn. Ví dụ: bạn có thể chỉ muốn khớp dòng đó bắt đầu bằng POP3_SERVER_NAME.
$ awk '/^POP3_SERVER_NAME/{print $NF}' test.dat
localhost
Sử dụng sed là một chút ít trực quan. (Cảm ơn, tôi biết về sự trớ trêu.) Địa chỉ dòng có chứa POP3_SERVER_NAME ở bất cứ đâu. Thay thế một chuỗi trống cho tất cả văn bản từ đầu dòng đến không gian tùy chọn theo sau "=". Sau đó in.
sed -n -e '/POP3_SERVER_NAME/ s/.*\= *//p' test.dat
awk
từ khoảng trắng sang thứ khác bằng cách sử dụng -F
. Ví dụ: -F "="
sẽ sử dụng =
như một dấu phân cách trong trường hợp bạn đề cập.
Thay thế p
lệnh bằng một thay thế loại bỏ phần không mong muốn của dòng.
sed -n '3 s/^[^=]*= *//p' installation.sh
Bạn có thể muốn khớp dòng theo từ khóa hơn là theo vị trí.
sed -n 's/^ *POP3_SERVER_NAME *= *//p' installation.sh
echo "POP3_SERVER_NAME = localhost" | sed 's/.*= //'
localhost
Hoặc nếu bạn có nội dung trong một tệp:
sed 's/.*= //' somefile.txt
localhost
Có vẻ như bạn đã có một tập tin cấu hình. Những gì bạn có thể làm tương tự như những gì Adam Siemeon / slm gợi ý:
sed -nr 's/[^=]+=\s*(.+)$/\1/p' filename
nơi [^=]
không bao gồm tất cả '=' nhân vật, +
cho biết một hoặc nhiều cùng một loại nhân vật, điều này tiếp theo là một thực tế =
, \s
bất kỳ khoảng trắng (bao gồm cả các tab \t
và dây chuyền mới \n
, \r\n
và không gian đơn giản '', trong khi *
phương tiện bằng không hoặc nhiều cùng loại , dấu ngoặc đơn bắt những gì bên trong để đặt các chuỗi ký tự trùng khớp vào các vị trí thay thế \ 1, \ 2, ..., \ n, $
có nghĩa là kết thúc một dòng. Điều này tuân theo mẫu thay thế điển hình của : s/.../.../modifiers
. Tùy chọn dòng lệnh -r
là viết tắt của cú pháp regex mở rộng (như một vấn đề thuận tiện) và -n
có nghĩa là đầu ra không có gì cho đến khi hoặc trừ khi được yêu cầu một cách rõ ràng. Công cụ p
sửa đổi in ra kết quả.
Bạn có thể thực hiện tìm kiếm toàn cầu với công cụ g
sửa đổi như:
sed -nr 's/[^=]+=\s*(.+)$/\1 /pg' filename # note the space after \1
để bạn có được một chuỗi phân cách bằng ' '
(có thể là \n
, \t
hoặc những gì có bạn) mà bạn có thể xử lý một cách dễ dàng.
Cả hai đều hợp lệ với điều kiện các giá trị của bạn đứng trước ký tự phương trình kéo dài đến cuối dòng và không được theo sau bởi các nhận xét hoặc các ký tự khác có ngữ nghĩa lệch khỏi một "giá trị" đơn giản.
Tôi không thể bình luận ở đây về bài viết của người khác. Để chỉ ra dòng chỉ cần vượt qua số dòng, trong trường hợp của bạn 3, trước s
hoặc trước trích dẫn char (giống như trong vim).
sed -nr '3s/[^=]+=\s*(.+)$/\1/p' filename
Xin hãy xem info sed
. Ví dụ, 3.2 và 4.7 được bạn đặc biệt quan tâm.
Vẻ đẹp của Linux / Unix là thường có nhiều hơn một cách để hoàn thành một cái gì đó. Trong trường hợp của op, có ít nhất bốn cách khác nhau để trích xuất tên máy chủ POP từ tệp:
grep POP3_SERVER_NAME installation.sh | cut -d'=' -f2
grep POP3_SERVER_NAME installation.sh | awk '{print $3}'
grep POP3_SERVER_NAME installation.sh | sed 's/.*= //'
sed -n 's/^.*POP3_SERVER_NAME = //p' installation.sh
awk
lệnh là tốt đẹp - nhưng chỉ khi bạn đã có không gian xung quanh=
. Nó sẽ không làm việc choPOP3_SERVER_NAME=localhost
.