Have a list of files, move them using one command

2

1

I have run a command which finds a lot of files based on some search criteria. It returns the files like so:

./somepath/somepath/file.something
./asdf/asdf/s.php
./etc/a.php
./a/b/c/d/e/f/g.jpg

So I was wondering, if I capture this output into a file (ie. one file per line), can anyone help me write a command which iterates through the file and moves the files one by one to a specified directory?

Thank you in advance.

mqchen

Posted 2010-11-02T14:41:32.923

Reputation: 133

Answers

3

while read -r filename
  do
  mv -- "$filename" directory
done < list_of_files.txt

Not tested (I'm on a work PC running Windows) but should work.

CarlF

Posted 2010-11-02T14:41:32.923

Reputation: 8 576

The basic approach is sound, but your original version was missing several protections against “unusual” filenames. Always use read -r, as plain read expands some backslashes. Always use double quotes around variable substitutions unless you know why not to; without the quotes, the shell would expand whitespace and \[?* in file names. Finally, -- before the file names on the mv command line protects a file name beginning with a - from being considered an option by the mv command. – Gilles 'SO- stop being evil' – 2010-11-02T23:28:20.803

You are absolutely correct. Dashed it off without proper care--thanks for the correction. – CarlF – 2010-11-03T12:35:47.340

Thanks! I also gave it a try myself and ended up with a 30 line php script. – mqchen – 2010-11-06T11:46:41.027

2

your_command | xargs -I% mv "%" dest_dir

If your command is find or you have some way of terminating the filenames with a null:

your_command | xargs -0 -I% mv "%" dest_dir

or

find [find-args] -print0 | xargs -0 -I% mv "%" dest_dir

Using nulls to terminate filenames allows this to work with filenames that may contain spaces, newlines, etc.

You can also use xargs to process your file if you've already created it:

xargs -a filename -I% mv "%" dest_dir

Paused until further notice.

Posted 2010-11-02T14:41:32.923

Reputation: 86 075

Why are you giving instructions on removing the files when he wants to move them? – frabjous – 2010-11-02T16:34:36.667

I'm betting Dennis copied that from an example and didn't customize it. – CarlF – 2010-11-02T16:36:34.380

No, I didn't copy it. I take full credit for the foul-up. I will correct my examples. – Paused until further notice. – 2010-11-02T17:13:28.030

@mqchen: Note the -I% in Dennis's answer. This is important: without it, xargs expects input quoted in a peculiar way and would fail if your file names contain characters such as whitespace and \'". – Gilles 'SO- stop being evil' – 2010-11-02T23:23:14.983

-1

Another option, if the filenames don't contain any whitespace, would be

mv `search_command_here` dest_directory

(The backtick syntax is also a bash-ism, but the question specifically states that this is on Linux and all major Linux distros use bash by default.)

Dave Sherohman

Posted 2010-11-02T14:41:32.923

Reputation: 5 143

The backtick syntax may be a Linux/Unix-ism, but it's not a Bashism. Every major shell uses it. Even the preferred $() syntax is not a Bashism as it's available in most modern shells and is specified by POSIX. – Paused until further notice. – 2010-11-02T17:17:14.140

Not only whitespace, but also wildcards (*?[) and backslashes in file names will be expanded by the shell with this command. – Gilles 'SO- stop being evil' – 2010-11-02T23:24:42.707