I wanted to move large amount of files from many directories which are under the parent directory in who I'm positioned.

I used following command with backticks:

mv -t directory1/directory2/directory3/ `ls -R | grep _2_3`

So I wanted to move the source of command in backticks to the destination directory which is 'directory3' which are find Recursively under my current directory ( parent one )

Is there any solution to do this with the current command? And what does this error mean exactly?


You will notice that ls -R outputs filenames. That is, it does not output pathnames. Therefore, if a file that contains the string _2_3 in its name is found in one of your subdirectories, there is no information about where that file is found in the output of ls -R (on the same line as the filename). This makes your command fail (the filename is not found in the current directory). It would also fail for any file that contains a space, tab or newline in its name, and would potentially also produce strange results if any filename contained filename globbing characters.

Instead, assuming you'd want to move files whose filenames end in _2_3 to a directory /directory1/directory2/directory3 (and that this directory is not a subdirectory of the current directory), then

find . -type f -name '*_2_3' -exec mv -t /directory1/directory2/directory3 {} +

would do that. This would find the pathnames of all regular files (not directories or named pipes, or symbolic links etc.) whose names end with _2_3 anywhere in or under the current directory, and would execute mv -t /directory1/directory2/directory3 with as many of these pathnames as possible in batches.

In the bash shell, you could possibly also do

shopt -s globstar
mv -t /directory1/directory2/directory3 **/*_2_3

unless the pattern expands to many thousands of names. The globstar shell option in bash enables the ** globbing pattern. It works like * but will match across / in pathnames. It would therefore find all names matching *_2_3 anywhere in or below the current directory. Note that this command does not care what type of name is matched, and might match directory names too, for example (but so would your ls -R approach do).

In the zsh shell, you could be more precise with the matching:

mv -t /directory1/directory2/directory3 **/*_2_3(.)

The (.) modifies the behaviour of the preceding pattern to only match regular files. The ** pattern is enabled by default in zsh.

If you wish to find files whose names contain _2_3, then simply change the *_2_3 bit of the filename pattern in the above commands to *_2_3*.

| improve this answer | |

The important part of the message is: No such file or directory. ls -R doesn't include the filepath. So mv have just the filename but cannot find it, because the path to it is missing.

Do this instead:

$ find ./ -name '*_2_3*' -exec mv -t directory1/directory2/directory3/ {} +
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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