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


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.

3
echo $xэто не отображать значениеx . printf '%s\n' "$x"было бы.
Стефан Шазелас

2
awk '{print $2}'печатает второе поле каждой строки ранее отображенного x.
Стефан Шазелас

9

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

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

вывод

[true]

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 и $означает в конце


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]}

2

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

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

зачем привлекать 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
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.