Bir dizgi değişkeninden ikinci sözcüğü çıkarma


11

"rtcpOnNbActive true"Bir değişkende saklanan bir dize var x. Bir alt dize olarak "true" ayıklamak ve bir değişken depolamak istiyorum. Bunu nasıl yapabilirim?


xAyıklamak istediğiniz alt dizeden hemen önce her zaman bir boşluk olacak mı?
PM 2Ring

Yanıtlar:


21

Bu şekilde deneyin:

y=$(echo $x | awk '{print $2}')
echo $y
  • echo $xdeğerini göster x.
  • awk '{print $2}'önceden görüntülenen ikinci alanı yazdırır x.
  • $(... )çıktıyı tutun ve atamasına izin verin y.

3
echo $xolduğu değil değerini göstermekx . printf '%s\n' "$x"olabilir.
Stéphane Chazelas

2
awk '{print $2}'önceden görüntülenen her satırın ikinci alanını yazdırır x.
Stéphane Chazelas

9

Ayıklamak istediğiniz alt dizeden önce en az bir boşluk olduğunu (ve alt dizenin boşluk içermediğini) varsayarsak, bunu basit bir parametre genişletmesiyle yapabilirsiniz:

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

çıktı

[true]

3
echobaşlamamış -ve herhangi bir kaçış dizisi içermeyen değişmez bir dize dışında hiçbir şey için taşınabilir değildir. Davranışı, nasıl derlendiğine ve XPG_ECHOayarlanıp ayarlanmadığına bağlı olarak bash yerleşkesi için bile değişir . Dizenin kaçış dizisi içermediğini varsayarsak, bu iyi olmalı, ancak printf '[%s]\n' "$y"yine de daha iyidir.
nyuszika7h

1
@ nyuszika7h: İyi bir nokta, ve okuduktan sonra Stéphane Chazelas burada benzer şeyler söylüyor ve diğer son sorularda echo, bunun gibi "fırlatma" örneklerinde bile, değişkenlerin değerini göstermek için kullanma alışkanlığımı kırmalıyım .
PM 2Ring

4

awk kullanabilirsiniz:

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

NF geçerli kayıttaki alan sayısı

sed kullanarak:

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

dize ifadesi kullanarak:

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

grep kullanarak:

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

-o sadece tam eşleşmeyi verir [a-z]+, az harfiyle eşleşir ve $sonunda anlamına gelir


2
Sizin için başka bir sorunun içeriğini aynı soruda yayınlamayın , lütfen.
αғsнιη

1
başkaları ne cevap ????
Hackaholic

Değişken olarak kaydedebilir burada büyük bir anlaşma değil
Hackaholic

echobaşlamamış -ve herhangi bir kaçış dizisi içermeyen değişmez bir dize dışında hiçbir şey için taşınabilir değildir. Davranışı, nasıl derlendiğine ve XPG_ECHOayarlanıp ayarlanmadığına bağlı olarak bash yerleşkesi için bile değişir . Ayrıca, değişken genişletmeleri ve komut ikamesini her zaman iki kez vermelisiniz (bazı istisnalar dışında, gerekli olmadığı, ancak herhangi bir zarar vermediği). OP gibi bir dize ile, bu iyi olmalı, ancak emin olmak printf '%s\n' "${a##* }"istiyorsanız daha iyi olurdu.
nyuszika7h

3

Bunun için bash dizileri kullanmak mümkündür, örneğin:

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

2

Sen kullanabilirsiniz readyerleşik

read -r _ y <<<"$x"
printf "%s\n" "$y"
true

neden dahil read? Bu readbölünmeyi yapmaz - değil $IFS. Bazı nedenlerden dolayı, birçok kişi w / $IFS sadeceread dahil olduğunda bölmek için Tamam düşünün . Sadece yapabilirsin: set -f; IFS=' '; printf %.0s%s $xya da her neyse. Her durumda - $IFSdeğerini burada belirtmeniz gerekir .
mikeserv

@mikeserv, readkullanarak bölme yapıyor IFS, belgeleri kontrol edin . Read kullanmanın temel avantajı, değişkenleri (bir OP gereksinimi) ayarlaması ve dizeleri bölebileceği ve bir diziyi doldurabildiği göz önüne alındığında, bir dizeden rastgele alanları ayıklamak için iyi olmasıdır. Buna ek olarak, IFSburada varsayılan kabul ediyorum , ancak gerekirse ayarlamak için yeterince kolay IFS=$' \n\t' read -r _ y <<<"$x", hile yapacak
iruvar

hayır değil. readatar, $IFSböler. bir dizi doldurmak istiyorsanız, kullanın set- bu durumda yapay burada-string saçmalık gerekmez. unset IFSvarsayılan $ IFS davranışını alır.
mikeserv

@mikeserv, Noel kartı listemden çıktın.
iruvar

bah humbug. xmas emiciler için.
mikeserv
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.