Bash: Получить количество элементов в массиве, которое является результатом команды `ls`?$ {# a [@]} не работает - PullRequest
0 голосов
/ 03 марта 2019

Я получаю 15 самых последних файлов .jpg или .png из текущего каталога в массиве:

images=$(ls -1tr *.jpg *.png | tail -n 15)

В этом случае все работает нормально:

for i in ${images[*]}; do echo "Found this image: $i"; done

Это показывает мне 15 строк как:

Найдено это изображение: foo.jpg
Найдено это изображение: bar.png
Нашел это изображение: baz.jpg
(... и т.д ...)

Однако, когда я пытаюсь напечатать длину массива $images, вот так:

echo ${#images[@]}

Я всегда получаю:

1

Несмотря на то, что найдено несколько изображений, и вышеfor цикл над массивом $images действительно показывает несколько строк.

Что я делаю не так?Как узнать количество элементов в массиве?

1 Ответ

0 голосов
/ 03 марта 2019

Вы правильно получаете количество элементов, и оно действительно равно 1.

Поскольку вы знаете JS, вот ваш код на JavaScript, чтобы увидеть, что на самом деле происходит:

// Assign all filenames to a single index
var images = ["foo.jpg\nbar.jpg\nbaz.jpg"]

// Join all the elements on spaces, then split them up on whitespace
var elements = images.join(" ").split(/[ \t\n]/);

for (var i in elements) {
  console.log("Found this image: " + elements[i]);
}
console.log("Array length: " + images.length);

Вывод:

Found this image: foo.jpg
Found this image: bar.jpg
Found this image: baz.jpg
Array length: 1

Вот что вы вместо этого хотели сделать в Bash:

images=( $(ls -1tr *.jpg *.png | tail -n 15) )
for i in "${images[@]}"; do echo "Found this image: $i"; done
echo "${#images[@]}"

Синтаксический анализ ls вывод считается хрупким: приведенный выше код по-прежнему разделяется на пробелы, поэтому My Image.jpg превратится в My и Image.jpg.

К сожалению, простой, хорошей замены нет, когда вам нужны файлы, отсортированные по дате модификации, но это позволяет избежать проблем, когда файлы содержат * или пробелы (Bash 4+):

mapfile -t images < <(ls -tr *.jpg *.png | tail -n 15)
for i in "${images[@]}"; do echo "Found this image: $i"; done
echo "${#images[@]}"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...