Trích xuất từ ​​chuỗi bằng grep / sed / awk


12

Tôi có một chuỗi

00:28:04 /usr/lib/jvm/jre/bin/java -DJDBC_CONNECTION_STRING= -Dspring.profiles.active=qa -XX:MaxPermSize=256

và muốn trích từ qatheo sau -Dspring.profiles.active.

Tôi có chuỗi lưu trong tệp text.txt chỉ để demo trên đó.

Khi tôi làm

grep -r -o "spring.profiles.active=" text.txt

Kết quả là spring.profiles.active=

Từ này không phải lúc nào cũng được qa, nó có thể prodhoặc dev.

Những gì tôi muốn làm là tìm ra lời spring.profiles.activesau khi các =chiết xuất từ đó.

Tôi muốn shell script này vì tôi sử dụng từ để cấu hình các mục khác trên máy chủ.

Điều này có thể không và nếu vậy, làm thế nào để tôi làm điều đó.


Tôi đoán đã có các cuộc hội thoại meta về vấn đề này rồi, nhưng câu hỏi này hoàn toàn không cụ thể đối với Ubuntu. Tại sao nó ở đây thay vì unix.stackexchange.com ?
Tony Adams

@TonyAdams Có, có: các câu hỏi xử lý văn bản đã được trình bày gián tiếp ở đây , và dù sao đi nữa, chúng luôn được xem xét theo chủ đề và không bao giờ đóng / di chuyển; về tính đặc thù của Ubuntu, đã được đề cập nhiều lần, hai lần gần đây ở đây và trong bản sao và một lần ở đây .
kos

câu hỏi hay! : D
máy tính

Câu trả lời:


18

Bạn có thể sử dụng grepvới PCRE ( -P):

grep -Po 'spring.profiles.active=\K[^ ]+' <<<'.....string.....'
  • spring.profiles.active=sẽ phù hợp với chuỗi con này theo nghĩa đen, \Ksẽ loại bỏ trận đấu

  • [^ ]+sẽ chọn phần mong muốn tức là phần sau spring.profiles.active=, cho đến không gian tiếp theo

Đối với một tập tin:

grep -Po 'spring.profiles.active=\K[^ ]+' file.txt

Thí dụ:

% grep -Po 'spring.profiles.active=\K[^ ]+' <<<'00:28:04 /usr/lib/jvm/jre/bin/java -DJDBC_CONNECTION_STRING= -Dspring.profiles.active=qa -XX:MaxPermSize=256'
qa

sed sẽ có logic tương tự:

sed -r 's/.*spring.profiles.active=([^ ]+).*/\1/' <<<'.....string.....'

Thí dụ:

% sed -r 's/.*spring.profiles.active=([^ ]+).*/\1/' <<<'00:28:04 /usr/lib/jvm/jre/bin/java -DJDBC_CONNECTION_STRING= -Dspring.profiles.active=qa -XX:MaxPermSize=256'
qa

Xử lý lỗi:

Trong tập lệnh của bạn, bạn có thể muốn xử lý trường hợp không khớp, nói cách khác là chuỗi gốc của bạn không chứa spring.profiles.active=. Trong sedví dụ trên , bạn có được toàn bộ chuỗi gốc, có thể tạo ra các vấn đề:

% var="$(sed -r 's/.*spring.profiles.active=([^ ]+).*/\1/' <<<'00:28:04 /usr/lib/jvm/jre/bin/java -DJDBC_CONNECTION_STRING= -XX:MaxPermSize=256')"
% echo $var
00:28:04 /usr/lib/jvm/jre/bin/java -DJDBC_CONNECTION_STRING= -XX:MaxPermSize=256

Nếu bạn muốn có được chuỗi trống khi không có kết quả khớp, hãy thêm -ntùy chọn vào sedlệnh và ptùy chọn cho sed slệnh, như sau:

% var="$(sed -rn 's/.*spring.profiles.active=([^ ]+).*/\1/p' <<<'00:28:04 /usr/lib/jvm/jre/bin/java -DJDBC_CONNECTION_STRING= -XX:MaxPermSize=256')"
% echo $var

% var="$(sed -rn 's/.*spring.profiles.active=([^ ]+).*/\1/p' <<<'00:28:04 /usr/lib/jvm/jre/bin/java -DJDBC_CONNECTION_STRING= -Dspring.profiles.active=qa -XX:MaxPermSize=256')"
% echo $var
qa

Sau đó, bạn có thể kiểm tra xem $ var có trống hay không.


Cảm ơn @heemay, hoạt động hoàn hảo. Bây giờ tôi chỉ cần kịch bản đó. Tôi sẽ đánh dấu nó như đã trả lời
Gman

@heemay bạn có biết làm thế nào tôi có thể viết kịch bản này không. Tôi có nó trong một kịch bản và khi nó chạy nó trở lại qa. Tôi muốn lưu kết quả trong một biến gọi là env và sau đó so sánh nó với một cái gì đó như thế nào. Nếu [env == qa]; sau đó // LÀM gì đó ... khác Làm gì đó ...
Gman

1
@Gman Yeah .. chỉ cần sử dụng thay thế lệnh: var="$(grep -Po 'spring.profiles.active=\K[^ ]+' file.txt)"thay thế file.txtbằng <<<'...string...'nếu đầu vào là một chuỗi, không phải là tệp..thì bạn có thể làmif [ "$var" = 'qa' ]; then do something; else do something; fi
heemayl

1

Sử dụng awk

awk -F"-Dspring.profiles.active=" '{sub(/ .*/,"",$2);print $2}' <<<'your_string'

hoặc là

awk -F"-Dspring.profiles.active=" '{sub(/ .*/,"",$2);print $2}' your_file

Thí dụ

% awk -F"-Dspring.profiles.active=" '{sub(/ .*/,"",$2);print $2}' <<<'00:28:04 /usr/lib/jvm/jre/bin/java -DJDBC_CONNECTION_STRING= -Dspring.profiles.active=qa -XX:MaxPermSize=256'
qa

1

Tôi sẽ ném một Perl một trong hỗn hợp:

<<<'string' perl -lane '$F[3]=~s/.*?=//;print($F[3])'
  • -l: cho phép xử lý kết thúc dòng tự động. Nó có hai hiệu ứng riêng biệt. Đầu tiên, nó tự động nhai $ / (dấu tách bản ghi đầu vào) khi được sử dụng với -n hoặc -p. Thứ hai, nó gán $ \ (dấu tách bản ghi đầu ra) có giá trị octnum để bất kỳ câu lệnh in nào sẽ có dấu phân cách đó được thêm lại. Nếu octnum bị bỏ qua, đặt $ \ thành giá trị hiện tại là $ /.
  • -a: bật chế độ tự động nhận khi được sử dụng với -n hoặc -p. Lệnh chia ngầm định cho mảng @F được thực hiện như là điều đầu tiên bên trong vòng lặp ngầm định được tạo bởi -n hoặc -p.
  • n: khiến Perl giả định vòng lặp sau xung quanh chương trình của bạn, điều này làm cho nó lặp đi lặp lại qua các đối số tên tệp có phần giống như sed -n hoặc awk:

    LINE:
      while (<>) {
          ...             # your program goes here
      }
  • -e: có thể được sử dụng để nhập một dòng chương trình.
% <<<'00:28:04 /usr/lib/jvm/jre/bin/java -DJDBC_CONNECTION_STRING= -Dspring.profiles.active=qa -XX:MaxPermSize=256' perl -lane '$F[3]=~s/.*?=//;print($F[3])'
qa

regex ban đầu cũng có thể được sử dụng như thế này:perl -nle '/spring.profiles.active=\K([^ ]+)/ && print $1' <<<'00:28:04 /usr/lib/jvm/jre/bin/java -DJDBC_CONNECTION_STRING= -Dspring.profiles.active=qa -XX:MaxPermSize=256'
Manwe
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.