Баш.Как выбрать случайную строку из переменной, содержащей множество строк? - PullRequest
1 голос
/ 26 мая 2019
a=$(find ./ -name "*-*.txt")

Теперь мне нужно получить случайную строку от $ a , но shuf кричать на меня

b=$(shuf -n1 $a)

shuf: дополнительный операнд

В чем моя проблема?Спасибо!

Ответы [ 2 ]

1 голос
/ 26 мая 2019

По умолчанию shuf принимает один аргумент имени файла и перетасовывает содержимое этого файла. Вы хотите, чтобы он перемешал свои аргументы вместо этого; для этого используйте shuf -e:

b=$(shuf -e -n1 $a)

Кстати, здесь есть более тонкая проблема: он будет запутан именами файлов с пробелами и / или подстановочными символами. Возможно, этого не произойдет в вашей среде, но я предпочитаю использовать идиомы сценариев, которые не падают из-за смешных имен файлов. Чтобы защититься от этого, храните имена файлов в массиве, а не рассчитывайте на разделение слов, чтобы сказать, где останавливается и начинается следующее:

readarray -d '' -t arr < <(find ./ -name "*-*.txt" -print0)
b=$(shuf -en1 "${arr[@]}")

Если вам не нужно хранить список файлов, все еще проще:

b=$(find ./ -name "*-*.txt" -print0 | shuf -zn1 | tr -d '\0')
1 голос
/ 26 мая 2019

Для этого вы можете использовать $ RANDOM .

Примечания:

  • ${#array[@]} дает размер массива
  • $((min + RANDOM % max)) дает случайное целое число, тогда как max не включено.
  • Вы можете получить доступ к элементу массива по индексу index_number, например, ${array[index_number]}
# define array
a=()
while read line
do
    # read the file list line by line and add to the array
    a+=("$line")
done < <(find ./files -name '*-*.txt')

random_index=$((0 + RANDOM % ${#a[@]}))

echo ${a[$random_index]}
...