array=${ls -d */}
echo ${array[@]}
У мене є три каталогу: ww
ee
qq
. Я хочу їх у масиві, а потім надрукувати масив.
array=${ls -d */}
echo ${array[@]}
У мене є три каталогу: ww
ee
qq
. Я хочу їх у масиві, а потім надрукувати масив.
Відповіді:
Це було б це
array=($(ls -d */))
EDIT: Дивіться рішення Гордона Девіссона для більш загальної відповіді (тобто, якщо ваші імена файлів містять спеціальні символи). Ця відповідь - це просто корекція синтаксису.
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), а не друкувати "* /" (для stdout).
Чистіший спосіб створити масив імен підкаталогів - використовувати 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[@]}"