Как я могу перетасовать массив имен файлов, в которых есть пробелы? - PullRequest
0 голосов
/ 12 декабря 2018

У меня есть массив имен файлов, которые могут содержать пробелы в них.Я использую команду shuf, но она использует пробелы в именах файлов в качестве разделителя и разбивает имена файлов при перемешивании.Есть ли способ обойти это или я должен отказаться от команды shuf?Любые предложения?

#!/bin/bash

vids=()

vids+=("file with spaces.txt")

for arr in "${vids[@]}"; do
    echo -e "$arr\n"
done

vids=( $(shuf -e "${vids[@]}") )    #shuffle contents of array

for arr in "${vids[@]}"; do
    echo -e "$arr\n"
done

exit 0

Ouput:

file with spaces.txt

file

with

spaces.txt

Ответы [ 2 ]

0 голосов
/ 12 декабря 2018

@ janos уже объяснил проблему, поэтому я не буду ее дублировать.Но есть другой подход к решению проблемы: перемешать индексы массива (которые являются просто числами), а не сами записи, а затем скопировать элементы в новый массив в порядке перемешивания:

shuffledvids=()
for index in $(shuf -e "${!vids[@]}"); do    # The ! gets the indexes, rather than entries
    shuffledvids+=("${vids[index]}")
done
prinf '%s\n' "${shuffledvids[@]}"    # Another way to print array elements, one per line
0 голосов
/ 12 декабря 2018

Причина, по которой ваш подход не работает, заключается в том, что оболочка применяет разделение слов к выводу команды внутри $(...), и нет способа трактовать переводы строк как разделитель.Вы можете использовать mapfile для чтения строк в массив (в Bash 4 +):

mapfile -t vids < <(shuf -e "${vids[@]}")

или в старых версиях Bash вы можете использовать старый старомодный цикл while:

vids2=()
while read -r item; do
    vids2+=("$item")
done < <(shuf -e "${vids[@]}")
...