0

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$)")
do
  mv $files /resto
done

but I got a lot of errors

mv: cannot stat

sebasth
  • 14,872

2 Answers2

1

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,

#!/bin/bash

shopt -s extglob dotglob

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

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.

Kusalananda
  • 333,661
0

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.

Saïmonn
  • 171
  • 5
  • 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 04:52
  • @user2425924 i fixed the missing leading \;. Also, I think -execdir should do the trick for you. – Saïmonn Sep 26 '19 at 07:58
  • Works fine thanks again. Solved question – user2425924 Sep 26 '19 at 10:46
  • Wouldn't this also create rest directories in each and every subdirectory of the folder directories? I think there may also be a risk that find would potentially try to enter the newly created rest directory and create a new rest directory within that. – Kusalananda Sep 26 '19 at 11:05
  • I did it in a huge folder and worked as desired. – user2425924 Sep 26 '19 at 11:09