I have a directories in /media/home/Seagate Expansion Drive/Downloads/Java Spring Gurus/folder1 .../folder2 .../foldern

Inside every directory I have a *.mp4 file and different types of additional files (*.srt, *.pdf etc.). I want to keep all *.mp4 in folderx, create folderx/rest/ and move the other files there.

How do I do that?

I tried:

for files in $(find "/media/sergio/Seagate Expansion Drive/DOWNS/Spring Framework 5"  | grep -P "([.]srt$)|([.]pdf$)")
  mv $files /resto

but I got a lot of errors

mv: cannot stat


I don't really see the use of using find here. You know exactly where everything is so there's no need to go looking for files.

Instead, assuming that you're using the bash shell,


shopt -s extglob dotglob

for dirpath in '/media/home/Seagate Expansion Drive/Downloads/Java Spring Gurus'/folder*/
    mkdir -p "$dirpath"/rest &&
    mv -i "$dirpath"/!(*.mp4|rest) "$dirpath"/rest

This would loop over all your folder* directories. For each such directory, it would create a rest subdirectory within it and then move everything that doesn't match *.mp4 (or the rest directory itself) into it.

The extended globbing pattern !(*.mp4|rest) would match any name not ending with .mp4, and not rest.

The shell options extglob enables the use of extended globbing patterns in bash, and the dotglob shell option will allow shell globs to match hidden names.

| improve this answer | |

This command should do what you expect:

find "/media/sergio/Seagate Expansion Drive/DOWNS/Spring Framework 5" -type f \! -iname '*.mp4' -execdir mkdir -p rest \; -execdir mv "{}" rest/  \;

In this command:

  • -type f: only match files (avoid moving directories, symlink or special files)

  • \!: act as a logic "NOT"

  • -iname: select files matching on the name, case insensitive (Use -name if you want to match the case)

  • -execdir: runs a command from the subdirectory containing the matched file. We need two of them, one for creating the folder rest/ and the second one to move the file to it.

edit: add missing leading \;, use execdir and keep only one solution.

| improve this answer | |
  • Excellent ! Almost there ! I learn a lot with your answer... I tried : find "/media/sergio/Seagate Expansion Drive/DOWNS/Spring Framework 5" -type f -iname '*.mp4' -exec mv "{}" /resto but I received this error here ... find: missing argument to `-exec' – user2425924 Sep 25 '19 at 17:15
  • Without the -exec mv "{}" /resto I can see all the files – user2425924 Sep 25 '19 at 17:18
  • Solved ! Thanks ! I google it and finished using it ... -/resto \; – user2425924 Sep 25 '19 at 17:33
  • Not really solved ! Moved to a /resto (where ???) and not to a subfolder resto in each folder. Could you help me please ? – user2425924 Sep 26 '19 at 4:52
  • @user2425924 i fixed the missing leading \;. Also, I think -execdir should do the trick for you. – Saïmonn Sep 26 '19 at 7:58

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.