Подстановочный знак Bash не расширяет скрытые файлы

Проблема связана с пробелами в данных. Оболочка разделит строку на слова во всех пробелах, и цикл 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"

Это считывает данные из строки, как если бы они были взяты из файла.

Связанные:

3
27.08.2020, 00:39
2 ответа

Я понял! При более внимательном рассмотрении документации для shopt можно увидеть параметр dotglob, который можно использовать для включения имен файлов, начинающихся с точки!

Я добавил shopt -s dotglobв начало своего скрипта, и теперь он работает. В выводе теперь перечислены все скрытые файлы и каталоги (, кроме ./и ../).

Теперь мой скрипт выглядит так:

#!/bin/bash
shopt -s extglob
shopt -s dotglob

for i in "$(pwd)"/*; do
  echo "$i"
done
6
18.03.2021, 23:09

Обходной путь posix без dotglob

#!/bin/sh

for i in "$PWD"/* "$PWD"/.*
  do
    [ "${i##*/}" =. ] || \
    [ "${i##*/}" =.. ] || \
    [ "${i##*/}" = \* ] || \
    [ "${i##*/}" =.\* ] && continue

    echo "$i"
done
1
18.03.2021, 23:09

Теги

Похожие вопросы