Скрипт Bash - как заполнить массив?

Скажем, у меня есть эта структура каталогов:

DIRECTORY:

.........a

.........b

.........c

.........d

Что я хочу сделать, так это: я хочу хранить элементы каталога в массиве

что-то вроде: array = ls /home/user/DIRECTORY

так что array[0] содержит имя первого файла (то есть 'a')

array[1] == 'b' и т. д.

Спасибо за помощь


person user1926550    schedule 10.04.2013    source источник
comment
Означают ли что-нибудь все эти точки в списке каталогов?   -  person Keith Thompson    schedule 10.04.2013
comment
нет. точки показывают только «подэлементы»   -  person user1926550    schedule 10.04.2013
comment
Это также может быть полезно: linuxconfig.org/how-to-use- массивы в сценарии bash   -  person Antônio Medeiros    schedule 16.09.2019


Ответы (3)


Вы не можете просто сделать array = ls /home/user/DIRECTORY, потому что — даже с правильным синтаксисом — это даст вам не массив, а строку, которую вам придется анализировать, и Парсинг ls преследуется по закону. Однако вы можете использовать встроенные конструкции Bash для достижения желаемого:

#!/usr/bin/env bash

readonly YOUR_DIR="/home/daniel"

if [[ ! -d $YOUR_DIR ]]; then
    echo >&2 "$YOUR_DIR does not exist or is not a directory"
    exit 1
fi

OLD_PWD=$PWD
cd "$YOUR_DIR"

i=0
for file in *
do
    if [[ -f $file ]]; then
        array[$i]=$file
        i=$(($i+1))
    fi
done

cd "$OLD_PWD"
exit 0

Этот небольшой сценарий сохраняет имена всех обычных файлов (что означает отсутствие каталогов, ссылок, сокетов и т. д.), которые можно найти в $YOUR_DIR, в массив с именем array.

Надеюсь это поможет.

person Daniel Kamil Kozar    schedule 10.04.2013
comment
Это работает, но только для файлов. Я также хотел бы сохранить имя каталога в массиве (если есть) - person user1926550; 10.04.2013
comment
Просто измените if в цикле в соответствии с вашими потребностями. - person Daniel Kamil Kozar; 10.04.2013

Вариант 1, ручная петля:

dirtolist=/home/user/DIRECTORY
shopt -s nullglob    # In case there aren't any files
contentsarray=()
for filepath in "$dirtolist"/*; do
    contentsarray+=("$(basename "$filepath")")
done
shopt -u nullglob    # Optional, restore default behavior for unmatched file globs

Вариант 2, используя обман массива bash:

dirtolist=/home/user/DIRECTORY
shopt -s nullglob
contentspaths=("$dirtolist"/*)   # This makes an array of paths to the files
contentsarray=("${contentpaths[@]##*/}")  # This strips off the path portions, leaving just the filenames
shopt -u nullglob    # Optional, restore default behavior for unmatched file globs
person Gordon Davisson    schedule 10.04.2013

array=($(ls /home/user/DIRECTORY))

потом

echo ${array[0]}

будет равен первому файлу в этом каталоге.

person chunky_pie    schedule 15.12.2020