Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have a list of files, with their full paths, one per line in a file "files.txt"

I was trying to move all of those files from their original location to a new directory.

I CDed into the directory where they live now and issued

for file in ~/Desktop/files.txt do mv $file ~/newfolder

but nothing happens. I am sure I am missing something obvious

share|improve this question
You need some separators there, try to just echo it with: for file in ~/Desktop/files.txt; do echo $file; done. – nerdwaller Jan 18 '13 at 17:01
@nerdwaller that won't work, bash will just print "~/Desktop/files.txt" it won't read the file unless explicitly told to either by for n in $(cat files.txt); do something; done or while read n; do something; done < files.txt. – terdon Jan 18 '13 at 17:24
@terdon, I wanted to edit it when I realized I was on non-thinking autopilot but it was past the expiration. Thanks for pointing it out and providing the fix :) – nerdwaller Jan 18 '13 at 17:25
up vote 2 down vote accepted

bash won't read the contents of the file unless you tell it to.

for file in $(cat ~/Desktop/files.txt); do mv "$file" ~/newfolder; done
share|improve this answer
If this is on a single line, you would need ; between $() and do. – nerdwaller Jan 18 '13 at 17:20
thanks @nerdwaller - fixed – Nifle Jan 18 '13 at 17:24
@nifle Would this work if the files all had different paths, when a path might be /Users/lombardi/work files/myfile.png and another in the same file.txt /docs/file.jpg? – Steve Jan 18 '13 at 17:56
Useless use of cat, and your script breaks in multiple ways, even if a file just contains a space in its path. Please fix this, as this kind of a common cause for problems. – slhck Jan 18 '13 at 18:06
This still breaks on file names that contain spaces. Since IFS is set to any white space, a file name like Quarterly report.pdf will fail above, even though $file is quoted, since Bash will split loop arguments on the whitespace: first $file will contain "Quarterly" and on the next iteration it will contain "report.pdf". One workaround is to set IFS='\n', but a failsafe solution already exists in the < files.txt version. This is one of the reasons that it is not good to learn people to loop like this, since it will break sooner or later. – Daniel Andersson Jan 18 '13 at 20:29

You need to tell your loop to read the file, otherwise it is just executing:

mv ~/Desktop/files.txt ~/newfolder

In addition, as nerdwaller said, you need separators. Try this:

while read file; do mv "$file" ~/newfolder; done < ~/Desktop/files.txt

If your paths or file names contain spaces or other strange characters, you may need to do this:

while IFS= read -r file; do mv "$file" ~/newfolder; done < ~/Desktop/files.txt

Notice the quotes " around the $file variable.

share|improve this answer
Thanks for editing mine, I realized my error but was unable to correct (comment edit time limit) and was writing an answer when yours popped up. Thanks! – nerdwaller Jan 18 '13 at 17:21
Thanks, that works too but I found the other post to be easier to remember for the future. – Steve Jan 18 '13 at 17:47
No worries, they are both correct. – terdon Jan 18 '13 at 17:50
I was going to make the same edit as you did, thanks :) (Sorry, it's just that there are so many "good enough" or mostly wrong Bash loops around on the Internet…) – slhck Jan 18 '13 at 18:15
Yeah, I just checked. With while, it works somewhat okay. It's just the -r option should be used to retain backslashes, and setting IFS= makes read not trim any leading or trailing whitespace. It's for that causes issues. See: Don't Read Lines With For – slhck Jan 18 '13 at 18:29

If the filenames do not contain whitespace:

mv -t dest_dir $(< text.file)

is probably the most concise way.

If there is whitespace in the filenames

while IFS= read -r filename; do mv "$filename" dest_dir; done < test.file

is safe.

share|improve this answer


mv -t dest_dir $(sed 's|^|"|;s|$|"|' text.file)

also deals with filenames with spaces while still using a single mv command and no loop. Untested.

share|improve this answer
There are three other answers, all upvoted and one accepted. This answer is unexplained code that you labeled as untested. Why would someone use this answer? – fixer1234 Feb 20 at 18:03

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.