Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pass all elements in existing array to xargs

Tags:

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

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.

I want to replace mv ${FILES[@]} /path/to/destination with a line that passes ${FILES[@]} to xargs to move each file. I need to use xargs as 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.

#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?

Below are methods I've tried and their errors.

Attempt 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 xargs can be executed directly or not.

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:

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.

like image 568
Matt Avatar asked Oct 18 '13 15:10

Matt


People also ask

How do you pass arguments to xargs?

The -c flag to sh only accepts one argument while xargs is splitting the arguments on whitespace - that's why the double quoting works (one level to make it a single word for the shell, one for xargs).

Can we use xargs and standard input?

xargs is a Unix command which can be used to build and execute commands from standard input.

Why is xargs necessary?

It converts input from standard input into arguments to a command. Some commands such as grep and awk can take input either as command-line arguments or from the standard input. However, others such as cp and echo can only take input as arguments, which is why xargs is necessary.

What does the xargs command do?

The xargs command builds and executes commands provided through the standard input. It takes the input and converts it into a command argument for another command. This feature is particularly useful in file management, where xargs is used in combination with rm , cp , mkdir , and other similar commands.

How to pass array elements as arguments in a function?

If individual elements are to be passed as arguments, then array elements along with their subscripts must be given in function call. To receive the elements, simple variables are used in function definition.

How do I use multiple arguments in xargs?

We can use multiple commands with xargs by using the -I (initial arguments) option. This option defines a “replace-string.” Wherever the token for the replace-string appears in the command line, the values that were supplied to xargs are inserted.

How do I use xargs in Linux?

When used on its own, xargs prompts the user to enter a text string that it then passes to the echo command. The example shows an example input, followed by the output of the echo command. Note: The echo command is a built-in Linux feature that prints out arguments as the standard output.

What is the syntax for passing an array to a function?

The syntax for passing an array to a function is: Here, we have passed an int type array named marks to the function total (). The size of the array is 5. When we call a function by passing an array as the argument, only the name of the array is used.


1 Answers

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 xargs should work as expected:

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

Or if your filenames can contain newlines, you can do

printf "%s\0" "${FILES[@]}" | xargs -0 -i mv '{}' /path/to/destination 
like image 82
user000001 Avatar answered Oct 07 '22 01:10

user000001