
У меня есть строка:
one_two_three_four_five
Мне нужно сохранить в переменной A
значение two
и в переменной B
значение four
из указанной выше строки
Я использую кш.
решение1
Используйте cut
with _
в качестве разделителя полей и получите нужные поля:
A="$(cut -d'_' -f2 <<<'one_two_three_four_five')"
B="$(cut -d'_' -f4 <<<'one_two_three_four_five')"
echo
Вместо строки Here можно также использовать конвейер:
A="$(echo 'one_two_three_four_five' | cut -d'_' -f2)"
B="$(echo 'one_two_three_four_five' | cut -d'_' -f4)"
Пример:
$ s='one_two_three_four_five'
$ A="$(cut -d'_' -f2 <<<"$s")"
$ echo "$A"
two
$ B="$(cut -d'_' -f4 <<<"$s")"
$ echo "$B"
four
Помните, что если $s
содержит символы новой строки, то будет возвращена многострочная строка, содержащая 2- е /4 -е поле в каждой строке $s
, а не 2 -е /4 -е поле в $s
.
решение2
Хотелось бы увидеть awk
ответ, вот он:
A=$(awk -F_ '{print $2}' <<< 'one_two_three_four_five')
B=$(awk -F_ '{print $4}' <<< 'one_two_three_four_five')
решение3
Используя только конструкции POSIX sh, вы можете использоватьконструкции подстановки параметровдля разбора одного разделителя за раз. Обратите внимание, что этот код предполагает наличие необходимого количества полей, в противном случае последнее поле повторяется.
string='one_two_three_four_five'
remainder="$string"
first="${remainder%%_*}"; remainder="${remainder#*_}"
second="${remainder%%_*}"; remainder="${remainder#*_}"
third="${remainder%%_*}"; remainder="${remainder#*_}"
fourth="${remainder%%_*}"; remainder="${remainder#*_}"
В качестве альтернативы вы можете использовать замену параметра без кавычек с помощьюрасширение подстановочного знакаинвалиды иIFS
установить на символ-разделитель(это работает только в том случае, если разделитель представляет собой один непробельный символ или если любая последовательность пробелов является разделителем).
string='one_two_three_four_five'
set -f; IFS='_'
set -- $string
second=$2; fourth=$4
set +f; unset IFS
Это затирает позиционные параметры. Если вы делаете это в функции, то будут затронуты только позиционные параметры функции.
Еще один подход для строк, не содержащих символы новой строки, — использование read
встроенной функции.
IFS=_ read -r first second third fourth trail <<'EOF'
one_two_three_four_five
EOF
решение4
С помощью zsh
можно разбить строку (on _
) на массив:
non_empty_elements=(${(s:_:)string})
all_elements=("${(@s:_:)string}")
а затем получить доступ к каждому элементу через индекс массива:
print -r -- ${all_elements[4]}
Имейте в виду, что в zsh
(как и в большинстве других оболочек, но в отличие от ksh
/ bash
)Индексы массива начинаются с 1.
Или непосредственно в одном расширении:
print -r -- "${${(@s:_:)string}[4]}"
Или используйте анонимную функцию, чтобы элементы были доступны в ней $1
, $2
...:
(){print -r -- $4} "${(@s:_:)string}"