When I run the command

find dir_1 -type f -name 'f*'

I found 2 files there "file_11" and "file_22". Now I want to move those files to another directory "dir_2" using -exec with the "find" command. So I use this command.

find dir_1 -type f -name 'f*' -exec mv {} ../dir2 \;

This command works.

Now, there are also some ".txt" files in the directory "dir_1". I want to move these text files to "dir2" and also rename these files. so I use this command,

find dir_1 -type f -name '*.txt' -exec mv {} ../dir2/new_{} \;

But I am getting the error,

mv: cannot move 'dir_1/file1.txt' to '../dir2/new_dir_1/file1.txt': No such file or directory
mv: cannot move 'dir_1/file2.txt' to '../dir2/new_dir_1/file2.txt': No such file or directory

Can anyone help me.


1 Answer 1

find dir_1 -type f -name '*.txt' -exec \
    sh -c 'echo mv "$1" "/path/to/dir_2/new_${1##*/}"' sh_mv {} \;

the syntax ${parameter##word} is the shell parameter expansion. and cuts-up-to-last-prefix specified by word from its given paramter; here it strips the path part from the filename. so ./dir_1/sub_directory/file1.txt becomes just file1.txt and later added new_ to the filename.

the sh -c '...' construct is known as inline shell (here sh shell) and we open it in order to provide/build necessary parameters for the mv command to move &rename and using its parameter-expansion feature for that.

with sh -c '...' sh_mv {}, it's accepting two arguments, one is sh_mv (used as a label for the inline shell we open (parameter $0)); the {} argument will be the substitution of the fileName found by find command and will pass as next argument (parameter $1).

note: remove echo to perform actual mv which we used for dry-run to test.


You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .