array=${ls -d */}
echo ${array[@]}
У меня есть три каталога: ww
ee
qq
. Я хочу их в массиве, а затем распечатать массив.
array=${ls -d */}
echo ${array[@]}
У меня есть три каталога: ww
ee
qq
. Я хочу их в массиве, а затем распечатать массив.
Ответы:
Было бы это
array=($(ls -d */))
РЕДАКТИРОВАТЬ: см. Решение Гордона Дэвиссона для более общего ответа (например, если ваши имена файлов содержат специальные символы). Этот ответ - просто исправление синтаксиса.
ARR+=('$(ls -d */)')
функцию для редактирования элементов в массиве, используя одинарные кавычки для работы со специальными символами, чтобы добавить или удалить элементы в него. массив. Одиночные кавычки сохраняют буквальные символы и устраняют необходимость в экранировании, чтобы иметь дело с ними в именах каталогов.
declare -a ARR; ARR+=('$(ls -d "$INPUT_DIR"/*)')
возвращает только$(ls -d $INPUT_DIR/*)
ARR+=("$(ls -d */)")
должно сработать. Если не просто дайте мне знать.
По возможности следует избегать синтаксического анализа вывода ls
(см . Вики Грега по этой теме ). Обычно вывод ls
будет неоднозначным, если в любом из имен файлов есть забавные символы. Также обычно это пустая трата времени. В этом случае, когда вы выполняете ls -d */
, происходит то, что оболочка расширяется */
до списка подкаталогов (который уже является именно тем, что вам нужно), передает этот список в качестве аргументов в ls -d
, который просматривает каждый из них и говорит: «Да, это каталог. хорошо »и распечатывает его (в противоречивом, а иногда и неоднозначном формате). Команда ls
не делает ничего полезного!
Хорошо, хорошо, он делает одну полезную вещь: если нет подкаталогов, */
он останется как есть, ls
будет искать подкаталог с именем «*», но не находить его, печатать сообщение об ошибке, что он не существует (чтобы stderr), а не выводить «* /» (на стандартный вывод).
Более простой способ создать массив имен подкаталогов - использовать glob ( */
), не передавая его в ls
. Но чтобы избежать добавления "* /" в массив, если фактических подкаталогов нет, вы должны сначала установить nullglob (опять же, см . Вики Грега ):
shopt -s nullglob
array=(*/)
shopt -u nullglob # Turn off nullglob to make sure it doesn't interfere with anything later
echo "${array[@]}" # Note double-quotes to avoid extra parsing of funny characters in filenames
Если вы хотите распечатать сообщение об ошибке при отсутствии подкаталогов, вам лучше сделать это самостоятельно:
if (( ${#array[@]} == 0 )); then
echo "No subdirectories found" >&2
fi
/
использовать имя каталога?
ls
это простая команда. Его вывод - это строки. Bash очень хорошо разбирается в строках. Правильное регулярное выражение - это все, что необходимо для безопасного анализа ls
вывода.
ls
делают разные вещи с забавными / непечатаемыми символами в именах файлов, поэтому нет единого способа преобразовать его вывод в список имен файлов. И, как я уже сказал, на самом деле он не делает ничего полезного: если вы правильно проанализируете выводls -d */
, вы получите то же самое, что и получили бы напрямую */
(кроме случаев, когда совпадений нет, и это легко проверить).
A lazy sysadmin is a good sysadmin.
возможно, мой собственный ls
синтаксический анализ специфичен для той версии, которая у меня есть или к которой я привык, но пока у них не было проблем с дистрибутивами Linux, на которых я их тестировал. Я могу говорить только по опыту.
Это будет печатать файлы в этих каталогах построчно.
array=(ww/* ee/* qq/*)
printf "%s\n" "${array[@]}"