Mengekstrak kata kedua dari variabel string

11

Saya memiliki string yang "rtcpOnNbActive true"disimpan dalam variabel x. Saya ingin mengekstrak "true" sebagai substring dan menyimpan dalam variabel. Bagaimana saya bisa melakukan ini?

Pratibha Jain
sumber
Apakah akan selalu ada ruang xsebelum substring yang ingin Anda ekstrak?
PM 2Ring

Jawaban:

21

Coba dengan cara ini:

y=$(echo $x | awk '{print $2}')
echo $y
  • echo $xmenampilkan nilai x.
  • awk '{print $2}'mencetak bidang kedua dari tampilan sebelumnya x.
  • $(... )tahan output dan biarkan tetapkan ke y.
jherran
sumber
3
echo $xadalah tidak menampilkan nilaix . printf '%s\n' "$x"akan menjadi.
Stéphane Chazelas
2
awk '{print $2}'mencetak bidang kedua dari setiap baris yang sebelumnya ditampilkan x.
Stéphane Chazelas
9

Dengan asumsi bahwa setidaknya ada satu ruang sebelum substring yang ingin Anda ekstrak (dan bahwa substring tidak mengandung spasi), Anda dapat melakukan ini dengan perluasan parameter sederhana:

x="rtcpOnNbActive     true"
y="${x##* }"
echo "[$y]"

keluaran

[true]
PM 2Ring
sumber
3
echotidak portabel untuk apa pun selain string literal yang tidak dimulai -dan tidak mengandung urutan pelarian. Perilakunya bervariasi bahkan untuk bash bawaan, tergantung pada bagaimana itu dikompilasi, dan apakah XPG_ECHOdiatur. Dengan asumsi string tidak mengandung urutan escape, ini harus baik-baik saja, tetapi printf '[%s]\n' "$y"masih lebih baik.
nyuszika7h
1
@ nyuszika7h: Poin bagus, dan setelah membaca Stéphane Chazelas mengatakan hal-hal serupa di sini dan dalam pertanyaan-pertanyaan baru-baru ini saya benar-benar harus menghentikan kebiasaan saya menggunakan echountuk menampilkan nilai variabel, bahkan dalam contoh "membuang" seperti ini.
PM 2Ring
4

Anda dapat menggunakan awk:

echo "rtcpOnNbActive         true" | awk '{print $NF}'
true

NF jumlah bidang dalam catatan saat ini

menggunakan sed:

echo "rtcpOnNbActive         true" | sed 's/.* //g'
true

menggunakan ekspresi string:

 a="rtcpOnNbActive         true"
 echo ${a##* }
 true

menggunakan grep:

 echo "rtcpOnNbActive         true" | grep -Eo "[a-z]+$"
 true

-o hanya memberikan kecocokan persis, [a-z]+akan mencocokkan huruf dari az dan $berarti di akhir

Hackaholic
sumber
2
Tolong, jangan posting konten jawaban lain untuk Anda dalam pertanyaan yang sama.
αғsнιη
1
apa jawaban orang lain ????
Hackaholic
ia dapat menyimpannya dalam variabel itu bukan masalah besar di sini
Hackaholic
echotidak portabel untuk apa pun selain string literal yang tidak dimulai -dan tidak mengandung urutan pelarian. Perilakunya bervariasi bahkan untuk bash bawaan, tergantung pada bagaimana itu dikompilasi, dan apakah XPG_ECHOdiatur. Selain itu, Anda harus selalu menggandakan ekspansi variabel penawaran dan penggantian perintah (dengan pengecualian tertentu, di mana itu tidak perlu tetapi juga tidak membahayakan). Dengan string seperti OP, ini harus baik-baik saja, tetapi jika Anda ingin memastikan printf '%s\n' "${a##* }"akan lebih baik.
nyuszika7h
3

Dimungkinkan untuk menggunakan array bash untuk itu, misalnya:

arr="(first second third)"
echo ${arr[1]}
kenorb
sumber
2

Anda bisa menggunakan readbuilt-in

read -r _ y <<<"$x"
printf "%s\n" "$y"
true
iruvar
sumber
mengapa melibatkan read? Bukan itu readyang membagi - itu $IFS. Untuk beberapa alasan, banyak orang menganggap itu baik-baik saja untuk membagi dengan $IFS hanya ketika readterlibat. Anda bisa melakukan: set -f; IFS=' '; printf %.0s%s $xatau apa pun. Bagaimanapun - Anda perlu menentukan $IFSnilai di sini.
mikeserv
@ mikeserv, ia readmelakukan pemisahan menggunakan IFS, periksa dokumentasinya . Keuntungan utama menggunakan read adalah bahwa ia menetapkan variabel (yang merupakan persyaratan OP) dan mengingat bahwa ia dapat memecah string dan mengisi array, baik untuk mengekstraksi bidang acak dari string. Selain itu, saya mengasumsikan default di IFSsini, tetapi cukup mudah untuk mengatur jika diperlukan, IFS=$' \n\t' read -r _ y <<<"$x"akan melakukan trik
iruvar
tidak, tidak. readmenugaskan, $IFSmembagi. jika Anda ingin mengisi array, gunakan set- Anda tidak perlu omong kosong di sini-string buatan dalam kasus itu. unset IFSmendapat perilaku default $ IFS.
mikeserv
@ mikeserv, Anda keluar dari daftar kartu Natal saya.
iruvar
bah humbug. xmas adalah untuk pengisap.
mikeserv