Передавать все элементы в существующем массиве в xargs

Я пытаюсь передать массив путей файла к xargs, чтобы переместить их все в новое место. В настоящее время мой script работает следующим образом:

FILES=( /path/to/files/*identifier* )
if [ -f ${FILES[0]} ]
  then
    mv ${FILES[@]} /path/to/destination
fi

Причиной наличия ФАЙЛОВ в качестве массива было то, что if [ -f /path/to/files/*identifier* ] терпит неудачу, если поиск по шаблону возвращает несколько файлов. Проверяется только первый файл, поскольку перемещение будет выполняться, если существуют какие-либо файлы.

Я хочу заменить mv ${FILES[@]} /path/to/destination на строку, проходящую от ${FILES[@]} до xargs для перемещения каждого файла. Мне нужно использовать xargs, поскольку я ожидаю, что у вас будет достаточно файлов, чтобы перегрузить один mv. Благодаря исследованиям мне удалось найти методы перемещения файлов, которые я уже знаю, которые снова ищут файлы.

#Method 1
ls /path/to/files/*identifier* | xargs -i mv '{}' /path/to/destination

#Method 2
find /path/to/files/*identifier* | xargs -i mv '{}' /path/to/destination

Есть ли способ передать все элементы в существующем массиве ${FILES[@]} до xargs?

Ниже приведены методы, которые я пробовал, и их ошибки.

Попытка 1:

echo ${FILES[@]} | xargs -i mv '{}' /path/to/destination

Ошибка:

mv: cannot stat `/path/to/files/file1.zip /path/to/files/file2.zip /path/to/files/file3.zip /path/to/files/file4.zip': No such file or directory

Попытка 2: Я не был уверен, что xargs можно выполнить напрямую или нет.

xargs -i mv ${FILES[@]} /path/to/destination

Ошибка: Сообщение об ошибке не выводилось, но оно зависало после этой строки, пока я не остановил ее вручную.

Изменить: найти работы

Я попробовал следующее и переместил все файлы. Это лучший способ сделать это? И он перемещает файлы по одному, поэтому терминал не перегружен?

find ${FILES[@]} | xargs -i mv '{}' /path/to/destination

Изменить 2:

В будущем, я проверил приемлемый метод ответа по сравнению с методом в моем первом редактировании, используя time(). После выполнения обоих методов 4 раза мой метод имел среднее значение 0.659s, и принятый ответ был 0.667s. Таким образом, ни один из методов не работает быстрее, чем другой.

Ответ 1

Когда вы делаете

echo ${FILES[@]} | xargs -i mv '{}' /path/to/destination

xargs рассматривает всю строку как один аргумент. Вы должны разделить каждый элемент массива на новую строку, а затем xargs должен работать как ожидалось:

printf "%s\n" "${FILES[@]}" | xargs -i mv '{}' /path/to/destination

Или, если ваши имена файлов могут содержать символы новой строки, вы можете сделать

printf "%s\0" "${FILES[@]}" | xargs -0 -i mv '{}' /path/to/destination