У меня есть строка:
one_two_three_four_five
Мне нужно сохранить A
значение two
переменной и B
значение переменной four
из приведенной выше строки
Используйте cut
с _
в качестве разделителя полей и получите нужные поля:
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
$ echo $FILE
my_user/my_folder/file.csv
$ A="$(cut -d'/' -f2 <<<"$FILE")"
$ echo $A
[file]*
Вы знаете, что здесь происходит?echo "${s##*_}"
Используя только конструкции POSIX sh, вы можете использовать конструкции подстановки параметров для анализа одного разделителя за раз. Обратите внимание, что этот код предполагает наличие необходимого количества полей, в противном случае последнее поле повторяется.
В качестве альтернативы вы можете использовать подстановку параметров без кавычек с отключенным расширением по шаблону и
IFS
установить для него символ разделителя (это работает только в том случае, если разделитель представляет собой один непробельный символ или если любая последовательность пробелов является разделителем).Это сжимает позиционные параметры. Если вы делаете это в функции, это влияет только на позиционные параметры функции.
Еще один подход заключается в использовании
read
встроенного.источник
unset IFS
не возвращаетIFS
по умолчанию. Если после этого кто-тоOldIFS="$IFS"
будет иметь нулевое значение внутри OldIFS. Кроме того, предполагается, что предыдущее значение IFS является значением по умолчанию, что очень возможно (и полезно), чтобы не быть. Единственное правильное решение - сохранитьold="$IFS"
и позже восстановить с IFS = "$ old". Или ... используйте вложенную оболочку(...)
. Или, еще лучше, прочитайте мой ответ.unset IFS
не восстанавливаетIFS
значение по умолчанию, но возвращает разделение полей с эффектом по умолчанию. Да, это ограничение, но обычно оно приемлемо на практике. Проблема с подоболочкой состоит в том, что нам нужно извлечь из нее данные. Я показываю решение, которое не меняет состояние в конце, сread
. (Он работает в оболочках POSIX, но IIRC не в оболочке Bourne, потому что он будет запускатьсяread
в подоболочке из-за нижеследующего документа.) Использование<<<
ответа as in you - это вариант, который работает только в ksh / bash / zsh.user/my_folder/[this_is_my_file]*
? Что я получу, когда буду следовать этим шагам[this_is_my_file]*
/
.Хотел увидеть
awk
ответ, так вот один:источник
awk -F_ '{print $NF}' <<< 'one_two_3_4_five'
Самый простой способ (для оболочек с <<<) это:
Использование временной переменной
$a
вместо$_
одной жалобы.В полном сценарии:
Без изменения IFS, без проблем
set -f
(расширение имени пути). Без изменений позиционных параметров ("$ @").Для решения, переносимого на все оболочки (да, включая все POSIX) без изменения IFS или
set -f
использования (немного более сложного) эквивалента heredoc:Поймите, что это решение (как здесь, так и при использовании
<<<
, удалит все завершающие символы новой строки.И что оно предназначено для переменного содержимого "в один слой".
Решения для мультилиний могут быть, но требуют более сложных конструкций.
В bash версии 4.4 возможно очень простое решение
Не существует эквивалента для оболочек POSIX, так как многие оболочки POSIX не имеют массивов.
Для оболочек, у которых есть массивы, может быть просто:
(проверено, работают ли в attsh, lksh, mksh, ksh и bash)
Но с большим количеством дополнительной сантехники для сохранения и сброса переменных и опций:
В zsh массивы начинаются с 1 и по умолчанию не разбивают строку.
Поэтому необходимо внести некоторые изменения, чтобы это работало в zsh.
источник
read
, просты, если OP не хочет извлекать 76-й и 127-й элементы из длинной строки ...readarray
может быть проще использовать в такой ситуации.С помощью
zsh
вы можете разбить строку (в_
) на массив:а затем получить доступ к каждому / любому элементу через индекс массива:
Имейте в виду, что в
zsh
(в отличие отksh
/bash
) индексы массива начинаются с 1 .источник
set -f
предупреждение к первому решению. ... звездочки*
может быть?set -f
? Я не используюread
/IFS
. Попробуйте мои решения со строкой, как*_*_*
или что-то еще ...Разрешено ли решение на Python?
источник
Другой пример awk; проще понять.
Может также использоваться с переменными.
Предположим:
this_str = "one_two_three_four_five"
Тогда работает следующее:
A = `echo $ {this_str} | awk -F_ '{print $ 1}' `
B =` echo $ {this_str} | awk -F_ '{print $ 2}' `
C =` echo $ {this_str} | awk -F_ '{print $ 3}' `
... и так далее ...
источник