Ekstrak kata dari string menggunakan grep / sed / awk

12

Saya punya string

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

dan ingin mengekstrak kata qayang mengikuti -Dspring.profiles.active.

Saya memiliki string simpan dalam file text.txt hanya untuk menunjukkannya.

Kapan saya melakukannya

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

Hasilnya adalah spring.profiles.active=

Kata ini tidak selalu qa, bisa prodatau dev.

Apa yang saya ingin lakukan adalah menemukan kata spring.profiles.activedan setelah itu =ekstrak kata.

Saya ingin membuat shell script ini karena saya menggunakan kata untuk mengkonfigurasi item lain di server.

Apakah ini mungkin dan jika demikian, bagaimana saya melakukannya.

Gman
sumber
Saya menduga sudah ada meta percakapan tentang hal ini, tetapi pertanyaan ini sama sekali tidak spesifik untuk Ubuntu. Mengapa ada di sini alih-alih unix.stackexchange.com ?
Tony Adams
@TonyAdams Ya ada: pertanyaan pemrosesan teks telah dibahas secara tidak langsung di sini , dan lagi pula, mereka selalu dianggap sesuai topik dan tidak pernah ditutup / dimigrasikan; pada kekhususan Ubuntu, yang telah dibahas beberapa kali, dua kali baru-baru ini di sini dan dalam duplikat dan sekali di sini .
kos
Pertanyaan bagus! : D
ncomputers

Jawaban:

19

Anda dapat menggunakan grepdengan PCRE ( -P):

grep -Po 'spring.profiles.active=\K[^ ]+' <<<'.....string.....'
  • spring.profiles.active=akan cocok dengan substring ini secara harfiah, \Kakan membuang pertandingan

  • [^ ]+akan memilih bagian yang diinginkan yaitu bagian setelah spring.profiles.active=, hingga ruang berikutnya

Untuk file:

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

Contoh:

% 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 akan mengambil logika serupa:

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

Contoh:

% 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

Menangani kesalahan:

Dalam skrip Anda, Anda mungkin ingin menangani case di mana tidak ada kecocokan, dengan kata lain di mana string asli Anda tidak mengandung spring.profiles.active=. Dalam sedcontoh di atas , Anda mendapatkan seluruh string asli, yang dapat menimbulkan masalah:

% 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

Jika Anda lebih suka mendapatkan string kosong ketika tidak ada kecocokan, tambahkan -nopsi ke sedperintah dan popsi ke sed sperintah, seperti ini:

% 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

Kemudian Anda dapat menguji apakah $ var kosong atau tidak.

heemayl
sumber
Terima kasih @heemay, bekerja dengan sempurna. sekarang saya hanya perlu menuliskannya. Saya akan menandainya sebagai jawaban
Gman
@heemay Anda tahu bagaimana saya bisa menulis ini. Saya memilikinya dalam sebuah skrip dan ketika dijalankan mengembalikan qa. Saya ingin menyimpan hasilnya dalam variabel yang disebut env dan kemudian membandingkannya dengan sesuatu seperti. Jika [env == qa]; lalu // LAKUKAN Sesuatu ... else Do Something ...
Gman
1
@ Ya Tuhan .. cukup gunakan substitusi perintah: var="$(grep -Po 'spring.profiles.active=\K[^ ]+' file.txt)"ganti file.txtdengan <<<'...string...'jika input adalah string, bukan file..kemudian Anda dapat melakukannyaif [ "$var" = 'qa' ]; then do something; else do something; fi
heemayl
1

Menggunakan awk

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

atau

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

Contoh

% 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
AB
sumber
1

Saya akan melemparkan satu Perl dalam campuran:

<<<'string' perl -lane '$F[3]=~s/.*?=//;print($F[3])'
  • -l: mengaktifkan pemrosesan akhir baris otomatis. Ini memiliki dua efek terpisah. Pertama, secara otomatis chomps $ / (pemisah rekaman input) saat digunakan dengan -n atau -p. Kedua, ia menetapkan $ \ (pemisah catatan output) untuk memiliki nilai octnum sehingga setiap pernyataan cetak akan memiliki pemisah yang ditambahkan kembali. Jika octnum dihilangkan, tetapkan $ \ ke nilai saat ini $ /.
  • -a: mengaktifkan mode autosplit saat digunakan dengan -n atau -p. Perintah split implisit ke array @F dilakukan sebagai hal pertama di dalam loop implisit saat diproduksi oleh -n atau -p.
  • n: menyebabkan Perl untuk mengasumsikan loop berikut di sekitar program Anda, yang membuatnya iterate atas argumen nama file agak seperti sed -n atau awk:

    LINE:
      while (<>) {
          ...             # your program goes here
      }
  • -e: dapat digunakan untuk memasukkan satu baris program.
% <<<'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
kos
sumber
regex asli dapat digunakan juga seperti ini: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