Проблема связана с пробелами в данных. Оболочка разделит строку на слова во всех пробелах, и цикл for
будет перебирать эти слова.
(Решение, которое не заменяет variable_list
массивом, см. в самом конце этого ответа.)
Вместо этого используйте правильный массив:
variable_list=(
"any:any:-a -b -c any"
"one:one:-c -b -f -m mul"
"mul:one:-c -b -f -m mul"
)
for var in "${variable_list[@]}"; do
c1=$( cut -d':' -f1 <<<"$var" )
c2=$( cut -d':' -f2 <<<"$var" )
c3=$( cut -d':' -f3- <<<"$var" )
printf 'c1==>%s and c2==>%s and c3==>%s\n' "$c1" "$c2" "$c3"
done
Использование массива гарантирует, что вы можете обращаться к каждому отдельному набору переменных как к отдельной записи массива, не полагаясь на то, что они будут разделены символом новой строки или каким-либо другим символом.
Код также использует «здесь -строки» в bash
для отправки строки вcut
(вместо echo
и канал ).
Или, что гораздо эффективнее,
variable_list=(
"any:any:-a -b -c any"
"one:one:-c -b -f -m mul"
"mul:one:-c -b -f -m mul"
)
for var in "${variable_list[@]}"; do
IFS=':' read -r c1 c2 c3 <<<"$var"
printf 'c1==>%s and c2==>%s and c3==>%s\n' "$c1" "$c2" "$c3"
done
Установка IFS
в качестве двоеточия для read
приведет к тому, что read
разделит ввод на двоеточия (, а не на пробелы, табуляции и символы новой строки ).
Обратите внимание, что все приведенные выше цитаты имеют важное значение. Без двойных кавычек оболочка будет выполнять разбиение слов и подстановку имен файлов для значений variable_list
, var
и трех переменных c
.
Связанные:
Если все, что вам нужно, это конкретный вывод, вы можете немного схитрить:
variable_list=(
"any:any:-a -b -c any"
"one:one:-c -b -f -m mul"
"mul:one:-c -b -f -m mul"
)
( IFS=':'; set -f; printf 'c1==>%s and c2==>%s and c3==>%s\n' ${variable_list[@]} )
Это запускает printf
в подоболочке, поэтому настройка IFS
и параметр оболочки-f
(noglob
)не влияют на остальную часть скрипта. Установка здесь IFS
двоеточия заставит оболочку расширить массив без кавычекvariable_list
на три набора по три аргумента для printf
. printf
напечатает первые три в соответствии со своей строкой формата, а затем повторно использует этот формат для следующего набора из трех аргументов, пока все аргументы не будут обработаны.
Параметр set -f
не позволяет расширению variable_list
без кавычек запускать подстановку имен файлов,должны ли там быть какие-либо символы имени файла.
Использование символа новой строки -строки с разделителями:
variable_list="
any:any:-a -b -c any
one:one:-c -b -f -m mul
mul:one:-c -b -f -m mul"
while IFS= read -r var; do
IFS=':' read -r c1 c2 c3 <<<"$var"
printf 'c1==>%s and c2==>%s and c3==>%s\n' "$c1" "$c2" "$c3"
done <<<"$variable_list"
Это считывает данные из строки, как если бы они были взяты из файла.
Связанные:
Я понял! При более внимательном рассмотрении документации для shopt можно увидеть параметр dotglob
, который можно использовать для включения имен файлов, начинающихся с точки!
Я добавил shopt -s dotglob
в начало своего скрипта, и теперь он работает. В выводе теперь перечислены все скрытые файлы и каталоги (, кроме ./
и ../
).
Теперь мой скрипт выглядит так:
#!/bin/bash
shopt -s extglob
shopt -s dotglob
for i in "$(pwd)"/*; do
echo "$i"
done
Обходной путь posix без dotglob
#!/bin/sh
for i in "$PWD"/* "$PWD"/.*
do
[ "${i##*/}" =. ] || \
[ "${i##*/}" =.. ] || \
[ "${i##*/}" = \* ] || \
[ "${i##*/}" =.\* ] && continue
echo "$i"
done