С bash-4.4
и выше вы должны использовать:
readarray -d '' -t arr < <(
find . -type f -print0 | grep -zP 'some pattern')
Со старыми версиями bash
:
arr=()
while IFS= read -rd '' file; do
arr+=("$file")
done < <(find . -type f -print0 | grep -zP 'some pattern')
Или ( чтобы быть совместимым даже с более старыми версиями bash
, которые не имели синтаксиса arr+=()
в стиле zsh):
arr=() i=0
while IFS= read -rd '' file; do
arr[i++]=$line
done < <(find . -type f | grep -zP 'some pattern')
У вашего подхода есть несколько проблем:
-o
, grep
печатает только те части записей, которые соответствуют шаблону, а не полную запись. Вы не хотите этого здесь. Вывод find
с разделителями новой строки по умолчанию не может быть обработан постобработкой, так как символ новой строки так же действителен, как и любой другой в пути к файлу. Вам нужен вывод с разделителями NUL (например, -print0
в find
и -z
в grep
для обработки записей с разделителями NUL. IFS=
в read
.bash
,и без опции lastpipe
последняя часть конвейерной линии выполняется в подоболочке, поэтому вы будете обновлять только $arr
этой подоболочки.