Cách trích xuất một cặp giá trị khóa từ lệnh ps


10

Tôi đang cố gắng trích xuất tên ứng dụng từ pslệnh như thế này:

ps -af -u sas |grep "java"| grep -v "grep"

và nó tạo ra như sau:

sas 24431     1  0 Oct10 ?        00:51:08 /usr/lib/jvm/java-1.7.0-oracle-1.7.0.25.x86_64/jre/bin/java -Denv=DEV -Dapp.name=myApp -Xms512m -Xmx1g -Dlog.dir=/apps/java/logs

Tôi đã thử sử dụng egrepnhưng dường như không hoạt động:

ps -af -u sas|grep "java"| grep -v "grep"| egrep -o "-Dapp.name"

Làm thế nào tôi chỉ có thể nhận được -Dapp.namegiá trị "myApp"?


nếu grepmô hình bắt đầu bằng -, bạn cần đặt nó sau -etùy chọn. Nếu không, nó sẽ được coi là một lựa chọn. Nhưng điều đó sẽ chỉ phù hợp với từ này -Dapp.name, không phải là phần sau nó.
Barmar

luân phiên:grep -o -- -Dapp.name
strugee

bạn có thể sử dụng grep [j]avađể tránh lệnh grep -v "grep"(được thử nghiệm trên bash)
HVNSweeting

Câu trả lời:



8

Bạn không hiển thị thông báo lỗi bạn đang nhận nhưng có lẽ

grep: phương thức thiết bị chưa biết

Đó là bởi vì, giống như tất cả hoặc ít nhất là hầu hết các chương trình dòng lệnh khác, grepgiả định rằng bất cứ điều gì bắt đầu bằng một -tùy chọn và cố gắng phân tích nó như vậy. Trong trường hợp này, -Dđược sử dụng để hướng dẫn grepcách xử lý tệp thiết bị (xem man grepđể biết chi tiết). Một cách để khắc phục điều này là sử dụng --cho grepbiết mọi thứ sau đây không phải là cờ tùy chọn.

Kết hợp điều đó với khả năng PCRE của GNU grep, bạn có thể làm:

ps -af -u sas | grep -v grep | grep -Po -- '*-\KDapp.name=[^\s]+'

Biểu thức chính quy tìm kiếm a -và loại bỏ nó ( \K), sau đó chuỗi Dapp.name=theo sau càng nhiều ký tự không phải không gian càng tốt. Đầu ra là:

Dapp.name=myApp

Nếu bạn muốn myAppphần được lưu trong một biến, tôi sẽ tìm kiếm phần đó một mình:

ps -af -u sas | grep -v grep | grep -Po -- '-Dapp.name=\K[^\s]+'

Để gán nó cho một biến:

$ app="$(ps -af -u sas | grep -v grep | grep -Po -- '-Dapp.name=\K[^\s]+')"
$ echo $app
myApp

Tuy nhiên, bạn không bao giờ nên grepđầu ra pscho loại điều này, đó là những gì pgrepdành cho:

app="$(pgrep -a java | grep -Po -- '^Dapp.name=\K[^\s]+')"

4
ps -af -u sas | sed -n '/[j]ava/s/.*-Dapp\.name=\([^ ]*\).*/\1/p'

3

Bất cứ lúc nào bạn sử dụng ps … | grep …và cần loại trừ grep khỏi kết quả, bạn đang làm sai.

Quy tắc zeroth của phân tích cú pháp đầu ra pslà sử dụng các công cụ đáng tin cậy hơn như pgrepnếu có sẵn. Nếu bạn có pgrep, sau đó pgrep -f javaliệt kê tất cả các quy trình đang chạy lệnh java. Tùy chọn -lthêm dòng lệnh cho mỗi quá trình.

Để trích xuất đối số -Dapp.name, bạn có thể sử dụng sed. Nối toàn bộ dòng, sắp xếp để nhồi phần thú vị trong một nhóm và in ra nhóm đó.

pgrep -lf java | sed -n 's/^.*-Dapp\.name=\([^ ]*\).*$/\1/p'

Nguyên tắc đầu tiên để phân tích cú pháp đầu ra pslà sử dụng tùy chọn -ođể chọn các trường mà bạn cần. Ở đây, bạn chỉ quan tâm đến các đối số lệnh, vì vậy chỉ in nó.

ps -e -o args= | sed -n 's/^.*-Dapp\.name=\([^ ]*\).*$/\1/p'

3

Phức tạp hơn các câu trả lời khác, nhưng điều này sử dụng getoptđể xử lý phân tích cú pháp cho bạn. Một thay thế khác.

getopt -aql 'Dapp.name:' $(\
    ps -af -u sas | grep java | grep -v grep | tr -s ' ' | cut -d' ' -f8-\
) | cut -d"'" -f2
  1. lệnh của bạn: ps -af -u sas | grep java | grep -v grep
  2. tr -s ' ' "ép" nhiều không gian vào một không gian duy nhất để chuẩn bị cho cut
  3. cut -d' ' -f8- chia dòng theo dấu cách và lấy tất cả các trường sau 8 bao gồm, kết quả là /usr/lib/jvm/java-1.7.0-oracle-1.7.0.25.x86_64/jre/bin/java -Denv=DEV -Dapp.name=myApp -Xms512m -Xmx1g -Dlog.dir=/apps/java/logs
  4. getopts -aql 'Dapp.name:' $(...)phân tích các tùy chọn lệnh và chỉ xuất ra tên dài phù hợp với Dapp.namengười có giá trị (ký hiệu là :), kết quả là--Dapp.name 'myApp' --
  5. cut -d"'" -f2 lấy những thứ trong dấu ngoặc đơn
  6. Kết quả là: myApp

0

Tôi sẽ sử dụng pgrepthay vì psnhư vậy:

$ pgrep -fa java | grep -op "(<=-Dapp.name=)\w+"

Điều này sẽ trả về tất cả các quy trình khớp javavà sau đó lọc những quy trình chỉ hiển thị những quy trình có chứa -Dapp.name=. Bit cuối cùng, \w+sẽ hiển thị tên chương trình, giả sử rằng nó không chứa khoảng trắng.

LƯU Ý: Công -Ptắc mở rộng grepkhả năng chỉ định mọi thứ bằng PCRE - Biểu thức chính quy tương thích Perl . Không phải tất cả các phiên bản grephỗ trợ nó, nhưng hầu hết đều được bao gồm trong các phiên bản Linux hiện đại hơn.

Nếu bạn muốn toàn bộ đầu ra khóa / giá trị thì hãy thay đổi những thứ như sau:

$ pgrep -fa java | grep -oP -- "-Dapp.name=\w+"
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.