Извлечение второго слова из строковой переменной

11

У меня есть строка, "rtcpOnNbActive true"хранящаяся в переменной x. Я хочу извлечь "true" как подстроку и сохранить в переменной. Как я могу это сделать?

Пратибха Джайн
источник
Всегда будет пробел xперед подстрокой, которую вы хотите извлечь?
PM 2Ring

Ответы:

21

Попробуйте так:

y=$(echo $x | awk '{print $2}')
echo $y
  • echo $xотобразить значение x.
  • awk '{print $2}'печатает второе поле ранее отображенного x.
  • $(... )удерживайте вывод и позвольте ему присвоить y.
jherran
источник
3
echo $xэто не отображать значениеx . printf '%s\n' "$x"было бы.
Стефан Шазелас
2
awk '{print $2}'печатает второе поле каждой строки ранее отображенного x.
Стефан Шазелас
9

Предполагая, что перед подстрокой есть хотя бы один пробел, который вы хотите извлечь (и что подстрока не содержит пробелов), вы можете сделать это с помощью простого расширения параметра:

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

вывод

[true]
PM 2Ring
источник
3
echoне переносится ни для чего, кроме литеральной строки, которая не начинается с -и не содержит escape-последовательностей. Его поведение варьируется даже для встроенного bash, в зависимости от того, как он был скомпилирован и установлен ли XPG_ECHO. Предполагая, что строка не содержит escape-последовательностей, это должно быть хорошо, но printf '[%s]\n' "$y"все же лучше.
nyuszika7h
1
@ nyuszika7h: Хороший вопрос, и после прочтения Стефана Шазеласа произнесите подобные вещи здесь и в других недавних вопросах, я действительно должен отказаться от своей привычки использовать echoдля отображения значения переменных, даже в таких «выбрасываемых» примерах, как этот.
PM 2Ring
4

Вы можете использовать awk:

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

NF номер поля в текущей записи

используя sed:

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

используя строковое выражение:

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

используя grep:

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

-o это дает только точное совпадение, [a-z]+будет соответствовать букве от az и $означает в конце

Hackaholic
источник
2
Не размещайте содержание другого ответа на ваш вопрос в том же вопросе, пожалуйста.
αғsнιη 13.12.14
1
на что другие отвечают ????
Hackaholic
он может сохранить это в переменной, это не имеет большого значения здесь
Hackaholic
echoне переносится ни для чего, кроме литеральной строки, которая не начинается с -и не содержит escape-последовательностей. Его поведение варьируется даже для встроенного bash, в зависимости от того, как он был скомпилирован и установлен ли XPG_ECHO. Кроме того, вы всегда должны использовать двойные кавычки для раскрытия переменных и подстановки команд (за некоторыми исключениями, когда это необязательно, но это также не приносит никакого вреда). Со строкой, подобной OP, это должно быть хорошо, но если вы хотите убедиться, printf '%s\n' "${a##* }"что будет лучше.
nyuszika7h
3

Для этого можно использовать массивы bash, например:

arr="(first second third)"
echo ${arr[1]}
kenorb
источник
2

Вы могли бы использовать readвстроенный

read -r _ y <<<"$x"
printf "%s\n" "$y"
true
Iruvar
источник
зачем привлекать read? Это не readто, что делает раскол - это так $IFS. По какой-то причине многие считают нормальным разделение $IFS только тогда, когда readэто происходит. Вы можете просто сделать: set -f; IFS=' '; printf %.0s%s $xили что угодно. В любом случае - здесь нужно указать $IFSзначение.
mikeserv
@mikeserv, он readиспользует разделение IFS, проверь документацию . Основным преимуществом использования read является то, что он устанавливает переменные (что является требованием OP) и, учитывая, что он может разбивать строки и заполнять массив, хорошо подходит для извлечения произвольных полей из строки. Кроме того, я предполагаю, что IFSздесь используется значение по умолчанию , но его достаточно легко установить, если необходимо, это IFS=$' \n\t' read -r _ y <<<"$x"поможет
iruvar
нет, это не так. readприсваивает, $IFSразбивает. если вы хотите заполнить массив, используйте set- в этом случае вам не нужна искусственная бессмысленная ерунда здесь. unset IFSполучает поведение $ IFS по умолчанию.
mikeserv
@mikeserv, ты не в моем списке рождественских открыток.
iruvar
Ба-хамбуг. Рождество для лохов.
mikeserv