Вы можете использовать awk
для захвата ip
и country
и сохранения в массив:
IFS=$'\n'
IP_country=( $(awk -F'[:"]' '/ip/ || /country/{ print $5}' <<<"$( wget... )") )
Тогда первый элемент — ip
, а следующий —country
:
printf '%s\n' "${IP_country[0]}"
1.2.3.4
printf '%s\n' "${IP_country[1]}"
IR
Или распечатать все элементы:
printf '%s\n' "${IP_country[@]}"
1.2.3.4
IR
Будущее чтение:
В Bash вы можете использовать read -a
и здесь строку -, чтобы разбить строку на массив:
path=/foo/bar/doo
IFS=/ read -r -a parts <<< "$path"
Это дало бы массив с четырьмя элементами (пустыми ), foo
, bar
и doo
.
Это не работает с путями, содержащими новые строки, так как read
по умолчанию интерпретирует новую строку как разделитель. Чтобы предотвратить это, вам нужно добавить -d ''
, но тогда есть проблема, что здесь строка -добавляет новую строку, которую затем нужно удалить из последнего элемента:
path=$'/path/with/new\nlines'
IFS=/ read -d '' -r -a parts <<< "$path"
parts[-1]=${parts[-1]%$'\n'}
(parts[-1]
относится к последнему элементу массива, а ${var%text}
расширяется до значения var
с удалением завершающей части, соответствующей text
.)
Также обратите внимание, что если путь может содержать повторяющиеся косые черты, например. foo//bar
, вы получите пустые элементы массива посередине. Точно так же, если путь заканчивается косой чертой, в конце вы получите пустой элемент.
Вы можете либо игнорировать их, либо предварительно обработать путь, чтобы удалить их, с помощью чего-то вроде этого, чтобы удалить повторяющиеся косые черты
shopt -s extglob
path="${path//+('/')/'/'}"
и удалить косую черту в конце:
shopt -s extglob
path="${path%+('/')}"
Но опять же, обратите внимание, что в начале имени пути двойная косая черта //foo
является зарезервированной специальной записью, отличной от одиночной (или тройной и т. д. )косой черты, но вы вряд ли чтобы увидеть это на практике, поэтому я проигнорирую это.
В bash
для односимвольных разделителей можно использовать оператор split+glob (, оставляя расширения без кавычек в контекстах списка )после отключения части glob:
string='foo/bar
baz/asd..'
IFS=/
set -o noglob
array=( $string )
Обратите внимание, что он разбивает string='/foo/'
на ""
и "foo"
только (так же, как и при разбиении string='/foo'
. Чтобы разделить на ""
, "foo"
и ""
, вы можете сделать:
IFS=/
set -o noglob
array=( $string'' )
Хотя это затем разбивает string=''
на один пустой элемент вместо нулевого элемента.
В zsh
(, который не выполняет split+glob при расширении без кавычек, за исключением sh
/ ksh
эмуляции ),вы можете использовать флаг расширения параметра s
, который не ограничен одиночными разделителями символов -:
array=( ${(s[/])string} )
, который удаляет пустые элементы, или:
array=( "${(@s[/])string}" )
Для сохранения пустых элементов. Затем /foo/
разбивается на ""
, "foo"
и ""
, а пустая строка — на нулевой элемент.
Вы можете разделить разделитель, хранящийся в переменной, с помощью:
array=( "${(@ps[$delimiter])string}" )
Флаг p
также позволяет вводить escape-последовательности, такие как \0
, \n
, хотя у этих двух есть флаги быстрого доступа:f
для разделения при переводе строки, 0
для разделения при нулевом значении (, полезные для разделить вывод find -print0
, grep -lZ
, sort -z
... например,files=( ${(0)"$(grep -lZ pattern -- *)"} )
).
В zsh
вы также можете связать переменную массива со скалярной переменной с заданным одиночным байтом в качестве разделителя. $path
в zsh
на самом деле является специальным массивом, который связан с $PATH
с :
в качестве разделителя таким же образом (, вдохновленнымcsh
). Вы можете сделать это для любой переменной, такой как:
typeset -T string array /
Для привязки/
-разделенного $string
к массиву $array
.