bash 将现有数组中的所有元素传递给 xargs

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19453618/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 08:21:06  来源:igfitidea点击:

Pass all elements in existing array to xargs

linuxbashunixterminalxargs

提问by Matt

I am trying to pass an array of file paths to xargsto move them all to a new location. My script is currently working as follows:

我正在尝试传递一组文件路径xargs以将它们全部移动到新位置。我的脚本目前工作如下:

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

The reason for having FILES as a array was because the if [ -f /path/to/files/*identifier* ]fails if the wildcard search returns multiple files. Only the first file is checked, because the move will be executed if any files exist.

将 FILES 作为数组的原因是因为if [ -f /path/to/files/*identifier* ]如果通配符搜索返回多个文件则失败。只检查第一个文件,因为如果存在任何文件,将执行移动。

I want to replace mv ${FILES[@]} /path/to/destinationwith a line that passes ${FILES[@]}to xargsto move each file. I need to use xargsas I expect to have enough files to overload a single mv. Through research I have only been able to find the methods of moving files that I already know which search for the files again.

我想,以取代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

Is there a way to can pass all elements in an existing array ${FILES[@]}to xargs?

有没有办法可以将现有数组中的所有元素传递${FILES[@]}xargs

Below are methods I've tried and their errors.

以下是我尝试过的方法及其错误。

Attempt 1:

尝试 1

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

Error:

错误:

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

Attempt 2: I wasn't sure if xargscan be executed directly or not.

尝试 2:我不确定是否xargs可以直接执行。

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

Error: No error message was output, but it hung after that line until I stopped it manually.

错误:没有输出错误消息,但它挂在该行之后,直到我手动停止它。

Edit: Find works

编辑:查找作品

I tried the following and it moved all the files. Is this the best way to do it? And is it moving the files one by one, so the terminal is not overloaded?

我尝试了以下操作,它移动了所有文件。这是最好的方法吗?并且它是一个一个地移动文件,所以终端不会超载吗?

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

Edit 2:

编辑2:

For future reference, I tested the accepted answer method versus the method in my first edit using time(). After running both methods 4 times, my method had an average of 0.659s and the accepted answer was 0.667s. So neither method works any faster than the other.

为了将来参考,我使用time(). 运行这两种方法 4 次后,我的方法平均为 0.659 秒,接受的答案为 0.667 秒。所以这两种方法的工作速度都比另一种快。

回答by user000001

When you do

当你做

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

xargs treats the entire line as a singe argument. You should split each element of the array to a new line, and then xargsshould work as expected:

xargs 将整行视为单个参数。您应该将数组的每个元素拆分为一个新行,然后xargs应该按预期工作:

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

Or if your filenames can contain newlines, you can do

或者,如果您的文件名可以包含换行符,您可以这样做

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