Не храните его в переменной, по крайней мере, в обычной строковой переменной.Строковая переменная не может сохранить разницу между пробелом внутри каждого аргумента и пробелом, разделяющим их.
grep -lr "$pattern" "$LOG_FILE_PATH" | while IFS= read -r file; do cp "$file" temp/; done
Также обратите внимание, что вам не нужно вырезать результат grep, так как *Флаг 1004 * дает вам только имена файлов, именно то, что вы хотели.-H
- это значение по умолчанию, поэтому оно не нужно, а -n
не нужно, если вы только собираетесь его отключить.
Это не будет работать, если у вас есть файлы, содержащие в своих именах символ новой строки.В качестве решения вы можете указать grep
(и read
) использовать NUL для разделителя.
grep -lr --null "$pattern" "$LOG_FILE_PATH" | while IFS= read -d $'\0' -r file; do cp "$file" temp/; done
В качестве альтернативы, вы можете использовать xargs
вместо while
+ read
:
grep -lr --null "$pattern" "$LOG_FILE_PATH" | xargs --null -I {} cp {} temp/
Если вам нужно сохранить его в переменной, используйте тот же шаблон, что и выше, чтобы сохранить его в переменной array .Таким образом, пробел не требуется в качестве разделителя аргументов.
declare -a files
while IFS= read -d $'\0' -r file; do files+=("$file"); done < <(grep -lr --null "$pattern" "$LOG_FILE_PATH")
cp "${files[@]}" temp/
Вот еще один способ сделать это (хотя это не будет работать, если имена файлов включают символы новой строки, так как mapfile
не поддерживает изменение разделителя):
mapfile -t files < <(grep -lr "$pattern" "$LOG_FILE_PATH")
cp "${files[@]}" temp/
Если количество копируемых файлов очень велико, решения while
и xargs
все равно будут работать, но те, которые просто объединяют весь массив в одну команду cp
, могут не работать.