Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I have inherited a folder structure on a project and would like to simplify it a bit. I have a root full of folders (1st level) and each of those folders has a number of folders in it (2nd level) and each of those folders has a some files inside. It looks something like this:

root
|-- dir1
|    |-- dir1.1
|    |      +- file1.txt
|    |-- dir1.2
|    |     +- file2.txt
|    +-- dir1.N
|          +- fileN.txt
|-- dir2
|    |-- dir2.1
|          +- file3.txt
|-- dir3
|    |-- dir3.1
|          +- file4.txt

etc.

I'd like to remove all of the x.1 folders, simplify the structure, and move all the files from those folders one level down:

root
|-- dir1
|     +- file1.txt
|     +- file2.txt
|     +- fileN.txt
|-- dir2
|     +- file3.txt
|-- dir3
|     +- file4.txt

How would I go about accomplishing something like this through bash/zsh?

share|improve this question
    
There is a Unix and Linux Stack Exchange site where you might get more answers. –  WindowsEscapist Dec 20 '12 at 2:54
1  
@WindowsEscapist: Yes, but shell scripting questions are welcome here, and they are often answered quickly and/or correctly. –  Scott Dec 20 '12 at 3:33
    
@user1064903: wouldn't that be "one level up"? –  akira Dec 20 '12 at 5:59
    
Well, Hi user. Please don't drop "user signature" everywhere. Your user card could be improved for doing that. It follows you everywhere. And, the "Thanks" won't be required while asking question. Instead, you could use "thanks" after getting the answer :-) –  Waffle's Crazy Peanut Dec 20 '12 at 6:10
    
@Scott I know, I'm just making a pre-emptive suggestion (plus the site needs a little attention IMO). –  WindowsEscapist Dec 20 '12 at 15:11

2 Answers 2

I don’t know whether this will work in zsh, but I expect that it will in bash (although I haven’t fully tested it):

for f in */*/*
do
        mv "$f" "$(dirname "$(dirname "$f")")"
done

for f in */*
do
        if [ –d "$f" ]
        then
                rmdir "$f"
        fi
done

P.S. In Unix (unlike botany; i.e., the real world), trees have their roots at the top.  Therefore, this operation would be considered moving files up the directory structure.

share|improve this answer
    
Thank you! That worked perfectly even though I got a bunch of "line 9: [: –d: unary operator expected" which is the "if [ -d "$f" ]" line. –  user1064903 Dec 20 '12 at 3:55
    
@user1064903: Interesting. Maybe if [[ –d "$f" ]] will work, but I would have expected either to be acceptable. –  Scott Dec 20 '12 at 17:08
for d in */*; do
    mv "$d"/* "$d"/..
    rm -r "$d"
done

This doesn't work if the second level contains empty directories or files.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.