newbie17
newbie17

Reputation: 197

Moving multiple files having spaces in name (Linux)

I have a directory which contains multiple files with spaces in their names. I want to find a pattern in the name and those file will be moved to some other directory. Now the problem is that when the particular pattern is found in a single file name, that file is moving to the destination path but when there are multiple files this method fails. Below is the code that I'm using :

for file in `find . -maxdepth 1 -name "*$pattern*xlsx" -type f`
do
 mv "$file" $destination/
done

Upvotes: 2

Views: 2517

Answers (4)

ComputerScience
ComputerScience

Reputation: 1

The top answer find . -maxdepth 1 -name "*$pattern*xlsx" -type f -exec mv {} $destination + isn't working for me, and the man pages of find -exec command {} + state the following:

one instance of `{}' is allowed within the command, and it must appear at the end, immediately before the `+'

So instead I propose: find . -maxdepth 1 -name "*$pattern*xlsx" -type f -exec mv -t ../All\ Exercises/ {} +

Upvotes: 0

joanis
joanis

Reputation: 12221

Sometimes, the logic to insert in the body of the loop could be complex enough to warrant an actual bash loop.

Here is a solution that works that way:

find . -maxdepth 1 -name "*$pattern*xlsx" -type f | while IFS= read -r file
do
   mv "$file" $destination/
done

Edit: kudos to @KamilCuk for the IFS=, to handle filenames with leading and trailing whitespace, and -r, to handle filenames with escaped backspace characters.

Known limitation: this solution will not work for filenames that have embedded newlines. For such cases, see the other answers to this question.

Solution from @Charles Duffy in comments to Moving files with whitespace what will work even with newlines in the file names:

  • add -print0 to the find command to terminate records with the NULL character
  • add -d '' to the read command to read records terminated by NULL
find . -maxdepth 1 -name "*$pattern*xlsx" -type f -print0 | while IFS= read -r -d '' file
do
   mv "$file" $destination/
done

Upvotes: 1

newbie17
newbie17

Reputation: 197

Working fine with following code

find . -maxdepth 1 -name "*$pattern*xlsx" -type f -print0 | xargs -I{} -0 mv {} "$destination/"

Upvotes: 4

jlliagre
jlliagre

Reputation: 30813

No need to use a loop:

find . -maxdepth 1 -name "*$pattern*xlsx" -type f -exec mv {} $destination +

Upvotes: 7

Related Questions