Search code examples
linuxbashdirectorymovecut

How can i move/group specific folders in bash?


I have a folder structure like the following:

2020-123-1
2020-123-2
2020-123-3
2020-124-1
2020-124-2
...

I need to create folders from the first 2 numbers and omit whatever follows the second dash (-). Then I need to put the prior folders under the newly created ones with the correct name.

2020-123
        ->2020-123-1
        ->2020-123-2
        ->2020-123-3
2020-124
        ->2020-124-1
        ->2020-124-2

I tried to write a script in bash like this:

ls -d */ > folder.txt
cut -f1,2 -d"-" folder.txt |cut -f1 -d"/" |sort|uniq  > mainfolder.txt
while read line; do mkdir $line ; done < mainfolder.txt 
while read line; do mv $(cut -f1,2 -d"-" $line) $line/ ; done < folder.txt

I couldn't make the last line work, I know it has issues.


Solution

  • Actually, you don't have to parse the directory names and build the hierarchy. You can make use of the -p option of mkdir, thus, an awk one-liner will do the job:

    awk -F'-' '{top=$1 FS $2;printf "mkdir -p %s; mv %s %s\n",top, $0, top}' dir.txt
    

    The output with your example:

    mkdir -p 2020-123; mv 2020-123-1 2020-123
    mkdir -p 2020-123; mv 2020-123-2 2020-123
    mkdir -p 2020-123; mv 2020-123-3 2020-123
    mkdir -p 2020-124; mv 2020-124-1 2020-124
    mkdir -p 2020-124; mv 2020-124-2 2020-124
    

    Note

    • This one-liner just print the commands without executing them, you just pipe the output to |sh if everything looks fine. Examine the output commands, change the printf format/values for adjustment.
    • I didn't quote the filenames, since your example doesn't contain any special chars. Do it if it is in the case.