Я пытаюсь построить массив в Bash имен файлов с моей камеры:
FILES=(2011-09-04 21.43.02.jpg
2011-09-05 10.23.14.jpg
2011-09-09 12.31.16.jpg
2011-09-11 08.43.12.jpg)
Как видите, в середине каждого имени файла есть пробел.
Я попытался обернуть каждое имя в кавычки и экранировать пробел с помощью обратной косой черты, ни один из которых не работает.
Когда я пытаюсь получить доступ к элементам массива, он продолжает обрабатывать пространство как ограничитель элементов.
Как я могу правильно захватить имена файлов с пробелом внутри имени?
FILES[0] = ...
? (Изменить: я только что сделал; не работает. Интересно).find . -maxdepth 1 -type f -iname \*.$1 -printf '%f\n'
); для элемента в $ {array [@]}; do echo $ element; сделаноОтветы:
Я думаю, что проблема может быть частично связана с тем, как вы получаете доступ к элементам. Если я делаю простое
for elem in $FILES
, я испытываю ту же проблему, что и вы. Однако, если я получу доступ к массиву через его индексы, он будет работать, если я добавлю элементы численно или через escape-коды:Любая из этих деклараций
$FILES
должна работать:или
или
источник
echo "${FILES[$i]}"
). Это не имеет значения дляecho
, но это будет для всего, что использует его в качестве имени файла.for f in "${FILES[@]}"
.#
вfor ((i = 0; i < ${#FILES[@]}; i++))
заявлении символ sharp ( ) ?Должно быть что-то не так с доступом к элементам массива. Вот как это делается:
Из справочной страницы bash :
Конечно, вы также должны использовать двойные кавычки при доступе к одному члену
источник
expands to a single word with the value of each array member separated by the first character of the IFS special variable
for elem in "${files[@]}"
то время как они естьfor elem in ${files[@]}
- таким образом, пробелы путают расширение и попытки выполнить отдельные слова.Вам нужно использовать IFS для остановки пробела в качестве разделителя элементов.
Если вы хотите разделить на основе. тогда просто сделайте IFS = "." Надеюсь, это поможет вам :)
источник
IFS=""
до построения массива .Я согласен с другими, что, скорее всего, как вы получаете доступ к элементам, это проблема. Цитирование имен файлов в массиве присваивается правильно:
Использование двойных кавычек вокруг любого массива формы
"${FILES[@]}"
разбивает массив на одно слово на элемент массива. Это не делает никакого разделения слова кроме этого.Использование
"${FILES[*]}"
также имеет особое значение, но оно объединяет элементы массива с первым символом $ IFS, в результате получается одно слово, что, вероятно, не то, что вам нужно.Использование пустого
${array[@]}
или${array[*]}
подчиненного результата этого расширения для дальнейшего разделения слов, так что вы получите слова, разделенные на пробелы (и все остальное$IFS
) вместо одного слова на элемент массива.Использование цикла for в стиле C также хорошо и позволяет избежать беспокойства по поводу разделения слов, если вы не уверены в этом:
источник
Бегство работает.
Вывод:
Заключение в кавычки также приводит к тому же результату.
источник
Если у вас был ваш массив, как это: #! / Bin / bash
Вы бы получили:
Я не знаю почему, но цикл разбивает пробелы и помещает их как отдельный элемент, даже если вы окружаете его кавычками.
Чтобы обойти это, вместо вызова элементов в массиве вы вызываете индексы, которые принимают полную строку, заключенную в кавычки. Это должно быть заключено в кавычки!
Тогда вы получите:
источник
Не совсем ответ на проблему цитирования / экранирования исходного вопроса, но, вероятно, что-то, что на самом деле было бы более полезным для операции:
Где, конечно, выражение должно быть адаптировано к конкретному требованию (например,
*.jpg
для всех или2001-09-11*.jpg
только для фотографий определенного дня).источник
Другое решение - использовать цикл while вместо цикла for:
источник
Если вы не застряли в использовании
bash
, различная обработка пробелов в именах файлов является одним из преимуществ оболочки fish . Рассмотрим каталог, который содержит два файла: «a b.txt» и «b c.txt». Вот разумное предположение при обработке списка файлов, созданных с помощью другой командыbash
, но это не удается из-за пробелов в именах файлов, с которыми вы столкнулись:С
fish
синтаксисом почти идентичен, но результат - то, что вы ожидаете:Это работает по-другому, потому что fish разбивает вывод команд на новые строки, а не пробелы.
Если у вас есть случай, когда вы хотите разделить пробелы, а не переводы строк, для
fish
этого есть очень читаемый синтаксис:источник
Я использовал для сброса значения IFS и отката, когда это было сделано.
Возможный вывод из цикла:
источник