LinuxQuestions.org
Latest LQ Deal: Linux Power User Bundle
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 10-18-2012, 12:38 PM   #1
Drigo
Member
 
Registered: Jun 2009
Posts: 111

Rep: Reputation: 17
Angry Folde tree...Move files from subdirectories to a parent directiory


So let say i have (in my situation I have about 1.6k directories):
ParentDirectory/A/aa/ab/ac/ad/12.txt
ParentDirectory/A/aa/ab/ac/ad/13.txt
ParentDirectory/A/aa/ab/ac/ad/14.txt
ParentDirectory/A/aa/ab/ac/ad/15.txt
ParentDirectory/A/aa/ab/ac/ad/16.txt
ParentDirectory/A/aa/ab/ac/ad/17.txt

ParentDirectory/B/aa/ab/ac/ad/12.txt
ParentDirectory/B/aa/ab/ac/ad/13.txt
ParentDirectory/B/aa/ab/ac/ad/14.txt
ParentDirectory/B/aa/ab/ac/ad/15.txt
ParentDirectory/B/aa/ab/ac/ad/16.txt
ParentDirectory/B/aa/ab/ac/ad/17.txt

ParentDirectory/C/aa/ab/ac/ad/12.txt
ParentDirectory/C/aa/ab/ac/ad/13.txt
ParentDirectory/C/aa/ab/ac/ad/14.txt
ParentDirectory/C/aa/ab/ac/ad/15.txt
ParentDirectory/C/aa/ab/ac/ad/16.txt
ParentDirectory/C/aa/ab/ac/ad/17.txt

I want to get rid of the subdirectories in between (aa/ab/ac/ad) and get a folder tree like this:

ParentDirectory/A/12.txt
ParentDirectory/A/13.txt
ParentDirectory/A/14.txt
ParentDirectory/A/15.txt
ParentDirectory/A/16.txt
ParentDirectory/A/17.txt

ParentDirectory/A/12.txt
ParentDirectory/B/13.txt
ParentDirectory/B/14.txt
ParentDirectory/B/15.txt
ParentDirectory/B/16.txt
ParentDirectory/B/17.txt

ParentDirectory/C/12.txt
ParentDirectory/C/13.txt
ParentDirectory/C/14.txt
ParentDirectory/C/15.txt
ParentDirectory/C/16.txt
ParentDirectory/C/17.txt


Thanks!
 
Old 10-18-2012, 01:13 PM   #2
JaseP
Senior Member
 
Registered: Jun 2002
Location: Eastern PA, USA
Distribution: K/Ubuntu 12.04/14.04, Scientific Linux 6.3/6.4, Android-x86, Pretty much all distros at one point...
Posts: 1,791

Rep: Reputation: 157Reputation: 157
Are the intermediate directories empty?
If so, easiest way is move everything in the ../ad/ directories to something like ../A-1/... and then just recursively delete ../A/... and all the empty sub-directories, and then rename /A-1 to /A ,... then do the same for the B and C directories...
 
Old 10-18-2012, 01:18 PM   #3
Drigo
Member
 
Registered: Jun 2009
Posts: 111

Original Poster
Rep: Reputation: 17
Not they are not empty of course they have another subdirectory within another subdirectory with the files I need. Your answer is basically my question. How do i do that using a single command? thanks though.
 
Old 10-18-2012, 01:29 PM   #4
JaseP
Senior Member
 
Registered: Jun 2002
Location: Eastern PA, USA
Distribution: K/Ubuntu 12.04/14.04, Scientific Linux 6.3/6.4, Android-x86, Pretty much all distros at one point...
Posts: 1,791

Rep: Reputation: 157Reputation: 157
What I meant was were they empty, except for the files you need,... or is it like:

ParentDirectory/A/aa/12.txt
ParentDirectory/A/aa/ab/13.txt
ParentDirectory/A/aa/ab/ac/14.txt
ParentDirectory/A/aa/ab/ac/ad/15.txt
ParentDirectory/A/aa/16.txt
ParentDirectory/A/aa/ab/17.txt

& One command?!?! This seems like a homework assignment...

A couple of hints,... you can chain commands to one line,... searches for *.* do not catch hidden files (so you need command one for each case),... and look at the command line switches for doing things recursively.
 
Old 10-18-2012, 01:41 PM   #5
Drigo
Member
 
Registered: Jun 2009
Posts: 111

Original Poster
Rep: Reputation: 17
They are empty if you dont consider the files I need. In other words, they look the way I show them. I tried:

mv ./Parent*/*/aa/ab/ac/ac/* ./Parent*/* but it doesnt do it recursively, it copies everything and renames them in one single folder....
 
Old 10-18-2012, 01:53 PM   #6
User\ Name=`echo $USER`
LQ Newbie
 
Registered: Oct 2012
Location: Oklahoma
Distribution: Red Hat, Ubuntu, Mac OS X
Posts: 25

Rep: Reputation: 4
Maybe this? You'd have to put it in a text file, and it's definitely not one command. I can't think of any other way than a for loop.
Code:
#!/bin/bash
IFS=$'\n'
for pardir in `ls -d */`; do
    cd $pardir
    for subdir in `ls -d */`; do 
        cd $subdir
        mv */*/*.* ./
        for unwanted in `ls`; do
            fext=`echo ${unwanted##*.}`
            if [ -d "$unwanted" ]; then
                rm -rf $unwanted
            fi
        done
       cd ..
    done
    cd ..
done
Of course this will only work if your directory structure is the same in every directory, and the files you want to move all have a .file_extention.
Anyway, modify as needed....

Last edited by User\ Name=`echo $USER`; 10-18-2012 at 01:54 PM.
 
Old 10-18-2012, 02:07 PM   #7
JaseP
Senior Member
 
Registered: Jun 2002
Location: Eastern PA, USA
Distribution: K/Ubuntu 12.04/14.04, Scientific Linux 6.3/6.4, Android-x86, Pretty much all distros at one point...
Posts: 1,791

Rep: Reputation: 157Reputation: 157
Try using find with -exec...

See the example showing something similar with the cp command vs. mv in an older thread;
http://www.linuxquestions.org/questi...folder-288830/

Then you would recursively delete the directories... and rename your temporary storage directory. Of course you need to watch how you define the files (assuming it's not just text files you're moving)...
 
Old 10-18-2012, 02:57 PM   #8
sneakyimp
Senior Member
 
Registered: Dec 2004
Posts: 1,001

Rep: Reputation: 67
this command should search the current directory recursively for text files and then move each text file up into the current directory -- you'd have to call it once for each of your target directories. you might have problems if any of the text files have the same name. before you try it, you should probably make a backup copy of the directory structure first.
Code:
find . -name '*.txt' -exec mv {} ./ \;
 
Old 10-18-2012, 03:32 PM   #9
shivaa
Senior Member
 
Registered: Jul 2012
Location: Grenoble, Fr.
Distribution: Sun Solaris, RHEL, Ubuntu, Debian 6.0
Posts: 1,800
Blog Entries: 4

Rep: Reputation: 286Reputation: 286Reputation: 286
I feel that your problem is not that complicated. It seems quite simple:
If you want only one sub-dir i.e. something like A under ParentDirectory, then first create an empty dir. under ParentDirectory as:
Code:
# cd ParentDirectory
# mkdir sampledir
(I assume new dir. name is sampledir)
Then move all text files from various directories into this sampledir directory as follow:
Code:
# cd ParentDirectory/A/aa/ab/ac/ad/
# mv ./*  ParentDirectory/sampledir/
Then remove the old dir. i.e. A and then rename sampledir again as A:
Code:
# \rm -rf ParentDirectory/A
(It will remove all empty/non-empty sub directories inside A)
Code:
# mv sampledir A
(Renaming sampledir to A)

Second situation is that if you want different sub dir. (for catagories your various text files) under ParentDirectory like A, B, C etc. then repeat the above steps for every new dir. you create and moving files into it.

Last edited by shivaa; 10-19-2012 at 12:53 AM.
 
Old 10-18-2012, 03:57 PM   #10
TobiSGD
Moderator
 
Registered: Dec 2009
Location: Germany
Distribution: Whatever fits the task best
Posts: 17,130
Blog Entries: 2

Rep: Reputation: 4825Reputation: 4825Reputation: 4825Reputation: 4825Reputation: 4825Reputation: 4825Reputation: 4825Reputation: 4825Reputation: 4825Reputation: 4825Reputation: 4825
Please, people, don't use fancy colors or such things for formatting code (or similar things), use code-tags for that.
 
Old 10-20-2012, 12:08 PM   #11
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Debian sid + kde 3.5 & 4.4
Posts: 6,823

Rep: Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957
I think something like this should work (untested):

Code:
#move all the text files up five directory levels
for fname in ParentDir/[ABC]/*/*/*/*/*.txt ; do

	echo mv "${fname}" "${fname%/*/*/*/*/*}" 

done

# Then remove the extra directories
echo rm -rf Parentdir/[ABC]/*/
The globbing patterns I used assume that there are no files or directories other than the ones you want to affect. Otherwise just modify the patterns to only match the ones you want.

Putting echo's at the beginning allow you to test the commands before actually committing to them. Just remove them after you've confirmed the correct action.


I also recommend reading what meninvenus posted above. It often pays to avoid over-complicating things. Remember the KISS principle.


Edit: I just noticed your mention that you're working with large numbers of directories. In which case the system might choke with too many arguments if you ran the above all at once. I suggest breaking the globbing matches up and running the above on smaller subsets at a time. Or use find instead, as mentioned above.

Last edited by David the H.; 10-20-2012 at 12:15 PM. Reason: fixt code error
 
Old 10-20-2012, 02:09 PM   #12
cbtshare
Member
 
Registered: Jul 2009
Posts: 610

Rep: Reputation: 42
I think either of these will work.[backup first then test]
Quote:
while true
do

mv /ParentDirectory/{A,B,C}/* /ParentDirectory/{A,B,C}/

rm -f /ParentDirectory/{A,B,C}/*

done
or

Quote:
find ./ -name '*.jpg' -exec mv '{}' ./ \;
 
Old 10-20-2012, 03:15 PM   #13
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Debian sid + kde 3.5 & 4.4
Posts: 6,823

Rep: Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957
I'm sorry to say, but this will not work.

Code:
while true
do

mv /ParentDirectory/{A,B,C}/* /ParentDirectory/{A,B,C}/

rm -f /ParentDirectory/{A,B,C}/*

done
To start with, it's better to use globbing than brace expansion in a situation like this. globs only expand to the files and directories that actually exist and match the pattern, but brace expansions generate strings first, then try to match them. Variations that fail to match non-existent files will generate errors.

But also your globbing patterns here only match one sub-level of the A,B,C directories, which is not the level that actually contains the files.

Next, remember that both types of expansion occur before the commands are run, so the mv line expands to the full list of files and directories, and everything will end up inside directory C after the first run.

Then similarly, the rm command is attempted on every file pattern at once, on every loop.

And finally, you've provided no way to break out of the loop, so it will run forever until externally killed.
 
Old 10-23-2012, 01:51 PM   #14
Drigo
Member
 
Registered: Jun 2009
Posts: 111

Original Poster
Rep: Reputation: 17
Tried this but didnt work...

find ./ -name '*.jpg' -exec mv '{}' ./ \;


of course I replaced *.jpg with what I watend but it looks like I am missing a end character because I get the
>
terminal line.


By the way, I can clearly create a script to do so which is what I would like to avoid (for those who gave me script answers). I would like to do this in the command line...

Looking forward for more answers...
 
Old 10-23-2012, 02:42 PM   #15
JaseP
Senior Member
 
Registered: Jun 2002
Location: Eastern PA, USA
Distribution: K/Ubuntu 12.04/14.04, Scientific Linux 6.3/6.4, Android-x86, Pretty much all distros at one point...
Posts: 1,791

Rep: Reputation: 157Reputation: 157
Semicolons and ampersands separate commands. Here's a nice little blog article about them;
http://www.skorks.com/2010/05/execut...ductivity-tip/
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] How do I move files from within many subdirectories to another one? gauchao Slackware 10 06-25-2011 02:07 PM
[SOLVED] move all ".txt" files, adding parent directory to filename mostofmonty Linux - Newbie 9 09-15-2009 09:39 AM
Move files from several subdirectories one level back Marinus Programming 2 01-21-2007 06:59 PM
Run script on every file contained within a parent directory and its subdirectories General Programming 4 05-15-2006 03:12 AM
move files to a series of subdirectories acid2000 Linux - General 1 09-01-2003 06:44 PM


All times are GMT -5. The time now is 06:43 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration