Wyodrębnianie drugiego słowa ze zmiennej łańcuchowej

11

Mam ciąg "rtcpOnNbActive true"przechowywany w zmiennej x. Chcę wyodrębnić „true” jako podciąg i zapisać w zmiennej. W jaki sposób mogę to zrobić?

Pratibha Jain
źródło
Czy zawsze będzie spacja xtuż przed podciągiem, który chcesz wyodrębnić?
PM 2,

Odpowiedzi:

21

Wypróbuj w ten sposób:

y=$(echo $x | awk '{print $2}')
echo $y
  • echo $xwyświetl wartość x.
  • awk '{print $2}'wypisuje drugie pole poprzednio wyświetlanego x.
  • $(... )przytrzymaj wynik i pozwól mu go przypisać y.
Jherran
źródło
3
echo $xjest nie wyświetla wartośćx . printf '%s\n' "$x"byłoby.
Stéphane Chazelas,
2
awk '{print $2}'wypisuje drugie pole każdego wiersza poprzednio wyświetlanego x.
Stéphane Chazelas,
9

Zakładając, że przed podciągiem jest co najmniej jedna spacja, którą chcesz wyodrębnić (i że podłańcuch nie zawiera spacji), możesz to zrobić za pomocą prostego rozszerzenia parametru:

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

wynik

[true]
PM 2 Ring
źródło
3
echonie jest przenośny na nic innego niż ciąg literalny, który nie zaczyna się od -i nie zawiera żadnych sekwencji specjalnych. Jego zachowanie różni się nawet dla wbudowanego basha, w zależności od tego, jak zostało skompilowane i czy XPG_ECHOjest ustawione. Zakładając, że ciąg nie zawiera sekwencji ucieczki, powinno to być w porządku, ale i tak printf '[%s]\n' "$y"jest lepsze.
nyuszika7h,
1
@ nyuszika7h: Dobra uwaga i po przeczytaniu Stéphane'a Chazelasa mówię tutaj podobne rzeczy i w innych ostatnich pytaniach naprawdę powinienem porzucić nawyk używania echowyświetlania wartości zmiennych, nawet w przykładach takich jak „wyrzucanie”.
PM 2,
4

możesz użyć awk:

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

NF liczba pól w bieżącym rekordzie

przy użyciu sed:

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

za pomocą wyrażenia łańcuchowego:

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

używając grep:

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

-o daje tylko dokładne dopasowanie, [a-z]+dopasuje literę od az i $oznacza na końcu

Hackaholic
źródło
2
Proszę nie zamieszczać treści innych odpowiedzi na to samo pytanie.
αғsнιη
1
co inni odpowiedzi ????
Hackaholic,
może uratować go w zmiennej, to nie jest wielka sprawa
Hackaholic
echonie jest przenośny na nic innego niż ciąg literalny, który nie zaczyna się od -i nie zawiera żadnych sekwencji specjalnych. Jego zachowanie różni się nawet dla wbudowanego basha, w zależności od tego, jak zostało skompilowane i czy XPG_ECHOjest ustawione. Powinieneś także zawsze podwójnie cytować rozszerzenia zmiennych i zastępować polecenia (z pewnymi wyjątkami, gdzie nie jest to konieczne, ale nie powoduje też żadnej szkody). Z ciągiem takim jak OP, powinno to być w porządku, ale jeśli chcesz się upewnić, printf '%s\n' "${a##* }"że będzie lepiej.
nyuszika7h,
3

Można do tego użyć tablic bash, np .:

arr="(first second third)"
echo ${arr[1]}
kenorb
źródło
2

Możesz użyć readwbudowanego

read -r _ y <<<"$x"
printf "%s\n" "$y"
true
iruvar
źródło
dlaczego wiązać read? To nie readrobi podziału - jest $IFS. Z jakiegoś powodu wiele osób uważa, że ​​podzielenie w / jest w porządku $IFS tylko wtedy, gdy readjest zaangażowany. Możesz po prostu zrobić: set -f; IFS=' '; printf %.0s%s $xlub cokolwiek. W każdym razie - musisz podać $IFStutaj wartość.
mikeserv
@ Mikeserv, readdokonuje podziału za pomocą IFS, sprawdź dokumentację . Główną zaletą korzystania z odczytu jest to, że ustawia zmienne (co jest wymaganiem OP), a biorąc pod uwagę, że może dzielić łańcuchy i zapełniać tablicę, nadaje się do wydobywania dowolnych pól z łańcucha. Dodatkowo jestem zakładając domyślnie IFStutaj, ale jest to dość łatwe do zbioru W razie potrzeby IFS=$' \n\t' read -r _ y <<<"$x"rade
Iruvar
nie, nie jest. readprzypisuje, $IFSdzieli. jeśli chcesz zapełnić tablicę, użyj set- w tym przypadku nie potrzebujesz sztucznego nonsensownego ciągu znaków. unset IFSdostaje domyślne zachowanie $ IFS.
mikeserv
@ Mikeserv, nie ma cię na liście kartek świątecznych.
iruvar,
bah humbug. Boże Narodzenie jest dla frajerów.
mikeserv