Разделить строку по разделителю и получить N-й элемент

Разделить строку по разделителю и получить N-й элемент

У меня есть строка:

one_two_three_four_five

Мне нужно сохранить в переменной Aзначение twoи в переменной Bзначение fourиз указанной выше строки

Я использую кш.

решение1

Используйте cutwith _в качестве разделителя полей и получите нужные поля:

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

Связанный контент