0

My files have the following structure:

11
--11a
-----a.jpg
-----b.jpg
-----....
--11b
-----d.jpg
-----g.jpg
...

I want to have all the .jpg files in one folder:

11
-a.jpg
-b.jpg
-d.jpg
-g.jpg
...

Basically I have subfolders with many .jpg files and I want to move all of them to one directory (e.g. parent).

I have tried: mv */*.jpg all but I get -bash: /bin/mv: Argument list too long.

Some posts suggest xargs and some other the find solution but unfortunately nothing seems to be working for me.

  • Are you certain all the file names are unique? How should conflicts be handled if not? I think find will give you a solution, but you need to answer these questions before I can suggest a solution. – AFH Oct 6 '16 at 23:09
  • Yes the file names are unique so there are no conflicts at all. – Menelaos Kotsollaris Oct 6 '16 at 23:45
  • This might work for osx as well. It is an elegant gui solution. – NonlinearFruit Oct 7 '16 at 16:07
0

If the file names are unique, use:

find {base folder}/11 -name "*.jpg" -exec mv {} {base folder}/11/ \;

where {base folder} is where the directory 11 resides.

This runs the mv command on each file in turn: it will be a lot slower than moving all the files in a single mv command, but there will be no restrictions on the length of the argument list.

If some of the file names could be in upper case, you can use -iname instead of -name. You can also add -n to make sure you do not overwrite a file which has been moved already (you need to check that your mv has this option - if not use -i, though this will prompt on conflicts).

You can get rid of any empty directories with:

rmdir {base folder}/11/*

You will need to investigate any directories that remain after this command.

  • How about find … -exec mv … +? It should pass multiple paths to mv, taking care of the line length though. – Kamil Maciorowski Oct 7 '16 at 16:09
  • @KamilMaciorowski - I'm sceptical: the line length will probably work out the same as in your original mv command, and subject to the same limitations. – AFH Oct 7 '16 at 22:34
  • Eh, even worse: it won't work at all. Now i see here that only a <plus-sign> that immediately follows an argument containing only the two characters "{}" shall punctuate the end of the primary expression. Still find {base folder}/11 -name "*.jpg" -exec mv -t {base folder}/11/ {} + should work (it appears this is exactly the purpose of -t option). The downside is the find will match already moved files. One can fight it specifying depth, or accept source and target are the same file error that should do no harm. – Kamil Maciorowski Oct 8 '16 at 4:51
  • There is an ordering option on find which allows subdirectories to be traversed in such a way that finding the same file in two places should not occur. Another approach is to process the files a directory at a time, instead of a file at a time: this should limit the mv parameter length. Use something like for d in {base folder}/11/; do [ -d "$d" ] && eval mv "$d/*.jpg" {base folder}/11/; done. This needs to be elaborated, as in this simple form it will generate errors, but it shows the approach. I've just had a gruelling 24 hours, so I can't work out all the niceties at present. – AFH Oct 8 '16 at 23:13
-1

This should be as easy as "mv /.your_extension ./"

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.