У меня есть следующий простой код ksh:
MY_LIST=first,second,third
NUM_IN_LIST=` echo $MY_LIST | sed s"/,/ /g" | wc -w `
print $NUM_IN_LIST
3
[[ $NUM_IN_LIST = 3 ]] && print match
but I dont get the match print -:(
может быть, потому что есть пробелы?
Могу ли я получить другие предложения по подсчету и печати слов в $MY_LIST? (после удаления разделителя ",")
решение1
Ваш пример мне подходит.
Вот альтернатива:
MY_LIST=first,second,third
saveIFS=$IFS
IFS=','
array=($MY_LIST)
IFS=$saveIFS
NUM_IN_LIST=${#array[@]}
print $NUM_IN_LIST
[[ $NUM_IN_LIST = 3 ]] && print match
решение2
Ваш код должен работать, но только если $MY_LIST
он не содержит никаких специальных символов:
echo $MY_LIST
должно бытьprintf %s "$MY_LIST"
илиprint -r -- "$MY_LIST"
. Отсутствие кавычек сообщает оболочке, что нужно расширять символы подстановки\\*?[
. Это также говорит оболочке, что нужно разделять слова пробелами, хотя здесь это не имело бы значения, если бы не следующая проблема.- Использование
echo
дополнительно приводит к интерпретации обратных косых черт и лидирования-
в некоторых обстоятельствах. - `sed s"/,/ /g" делает запятые и пробелы разделителями слов.
Дополнительная проблема, объясняющая, почему ваш последний тест не работает, заключается в том, что wc -w
выводит данные с ведущими пробелами, которые захвачены в $NUM_IN_LIST
. print $NUM_IN_LIST
выполняет разбиение слов на $NUM_IN_LIST
, поэтому в итоге просто печатает цифры; сделайте это, print "$NUM_IN_LIST"
чтобы увидеть разницу. [[ … ]]
Конструкция запрещает разбиение слов и =
является оператором сравнения строк, поэтому вам правильно говорят, что ' 3'
это не то же самое, что '3'
. [[ $NUM_IN_LIST -eq 3 ]]
или [ $NUM_IN_LIST = 3 ]
было бы верно (но ни то, ни другое не является настоящим решением, это просто ограниченные обходные пути).
Чистый способ ksh показать количество полей, разделенных запятыми, это
commas=${MY_LIST//[!,]/}
NUM_IN_LIST=${#commas}
Если кому-то нужно решение POSIX sh, замените первую строку на commas=$(printf %s "$MY_LIST" | tr -dc ,)
.