0

I have a folder structure like this: A big parent folder named Photos. This folder contains 900+ subfolders named a_000, a_001, a_002 etc.

Each of those subfolders contain more subfolders, named dir_001, dir_002 etc. And each of those subfolders contain lots of pictures (with unique names).

I want to move all these pictures contained in the subdirectories of a_xxx inside a_xxx. (where xxx could be 001, 002 etc)

After looking in similar questions around, this is the closest solution I came up with:

for file in *; do
  if [ -d $file ]; then
    cd $file; mv * ./; cd ..; 
  fi
done

Another solution I got is doing a bash script:

#!/bin/bash
dir1="/path/to/photos/"
subs= `ls $dir1`

for i in $subs; do
  mv $dir1/$i/*/* $dir1/$i/ 
done

Still, I'm missing something, can you help?

(Then it would be nice to discard the empty dir_yyy, but not much of a problem at the moment)

Mpampirina
  • 103
  • 3
  • 17
  • You should probably be asking this in the unix linix SE, as it is not really a programming question. But as a hint, doing something inside each a_xxx directory like `find . -type f -exec mv \{\} . \;` could be what you are looking for – infixed Nov 07 '16 at 15:48
  • Hi. I have 900+ folders, no way I'm gonna do this to each of them. I'm sorry if SO is not the place to post. It's that here i found the more relevant examples: [link1] (http://stackoverflow.com/questions/23546294/copy-files-from-subfolders-to-the-nearest-parent-directory-in-unix) and [link2] (http://stackoverflow.com/questions/22228718/using-for-loop-to-move-files-from-subdirectories-to-parent-directories) – Mpampirina Nov 07 '16 at 16:09
  • sure about `mv * ./;` part? because it seems to me that two points (for parent directory) would be needed somewhere, like `mv * ../;` perhaps – arhak Nov 07 '16 at 16:17
  • Nope, not sure at all... I have no idea of bash scripting. Gonna try slightly different versions to see what happens. – Mpampirina Nov 07 '16 at 16:21
  • The thing is you actually have two searches to do, one to iterate through your a_xxx directors, and then another within each of those to move the data files up into the particular a_xxx directory. It's difficult to do that with one command. Moving them all to one place would be much easier – infixed Nov 07 '16 at 16:29
  • Ehm. All the provided solutions do the job....Thank you guys. I wish I could give a star to each one of you! – Mpampirina Nov 08 '16 at 04:46

3 Answers3

3

You could try the following bash script :

#!/bin/bash

#needed in case we have empty folders
shopt -s nullglob

#we must write the full path here (no ~ character)
target="/path/to/photos"

#we use a glob to list the folders. parsing the output of ls is baaaaaaaddd !!!!
#for every folder in our photo folder ... 
for dir in "$target"/*/
do
    #we list the subdirectories ...
    for sub in "$dir"/*/
    do
        #and we move the content of the subdirectories to the parent
        mv "$sub"/* "$dir"
        #if you want to remove subdirectories once the copy is done, uncoment the next line
        #rm -r "$sub"
    done
done

Here is why you don't parse ls in bash

Community
  • 1
  • 1
Aserre
  • 4,916
  • 5
  • 33
  • 56
1

Make sure the directory where the files exist is correct (and complete) in the following script and try it:

#!/bin/bash
BigParentDir=Photos

for subdir in "$BigParentDir"/*/; do    # Select the a_001, a_002 subdirs
  for ssdir in "$subdir"/*/; do         # Select dir_001, … sub-subdirs
    for f in "$ssdir"/*; do             # Select the files to move
      if [[ -f $f ]]; do                # if indeed are files
         echo \
         mv "$ssdir"/* "$subdir"/       # Move the files.
      fi
    done
  done      
done

No file will be moved, just printed. If you are sure the script does what you want, comment the echo line and run it "for real".

1

You can try this

#!/bin/bash
dir1="/path/to/photos/"
subs= `ls $dir1`

cp /dev/null /tmp/newscript.sh

for i in $subs; do
  find $dir1/$i -type f -exec echo mv \'\{\}\' $dir1/$i \; >> /tmp/newscript.sh
done

then open /tmp/newscript.sh with an editor or less and see if looks like what you are trying to do.

if it does then execute it with sh -x /tmp/newscript.sh

infixed
  • 1,155
  • 7
  • 15