Разделение слов с использованием нескольких IFS
Будучи новичком в написании сценариев оболочки, мне не совсем понятны концепции цитирования и разбиения в bash. В приведенном ниже фрагменте:
array1=("france-country":"Italy-country":"singapore-country")
echo ${#array1[@]}
IFS=":-"
for i in ${array1[@]}
do
echo "$i"
done
unset IFS
с IFS быть :-
Я думал, что результатом будет:
france-country
Italy-country
belgium-country
как я процитировал их ("Франция"). Я думаю, что это не должно быть разделено на "-". Но результаты были:
france
country
Italy
country
belgium
country
Было бы здорово, если бы кто-то указал мне на мою ошибку в понимании.
2 ответа
Для вашей проблемы вы можете просто изменить разделитель полей как :
т.е. IFS=:
потому что название каждой страны разделено :
не :-
в вашем примере
array1=("france-country":"Italy-country":"singapore-country")
echo ${#array1[@]}
IFS=":"
for i in ${array1[@]}
do
echo "$i"
done
unset IFS
К вашему сведению, элементы массива в bash разделены space
так что вся строка "france-country":"Italy-country":"singapore-country"
поэтому является единственным элементом массива echo ${#array1[@]}
всегда будет 1
, Так что я не вижу никакого использования массива в этом примере. Простая переменная была бы достаточной.
Этот скрипт показывает, как разделить строку, разделенную двоеточиями, в массив Bash.
#!/usr/bin/env bash
words="france-country:Italy-country:singapore-country:Australia-country"
IFS=':' array1=($words)
numwords="${#array1[@]}"
for((i=0; i<numwords; i++));do
echo "$i: ${array1[i]}"
done
выход
0: france-country
1: Italy-country
2: singapore-country
3: Australia-country
Обратите внимание, что в
array1=($words)
мы не помещаем цитаты вокруг $words
, так как это предотвратит разделение слов.
Нам на самом деле не нужны цитаты в
words="france-country:Italy-country:singapore-country:Australia-country"
но кавычки (одинарные или двойные) были бы необходимы, если бы в этой строке были пробелы. Точно так же цитаты излишни в numwords="${#array1[@]}"
и многие программисты на Bash опускают их, потому что мы знаем результат ${#array1[@]}
никогда не будет пробелов в нем.
Хорошей идеей будет всегда использовать кавычки в Bash, если вы не уверены, что они вам не нужны, например, в случае array1=($words)
выше или при проведении испытаний с [[
... ]]
синтаксис.
Я предлагаю вам добавить BashGuide в закладки и просмотреть их FAQ. Но единственный способ по- настоящему изучить тайные способы цитирования и разделения в Bash - это написать множество скриптов.:)
Вы также можете найти ShellCheck полезным.