0

I have this structure of folders:

/Folder1/Folder2/output/0653/3547/0112945601/ 
/Folder1/Folder2/output/0653/3547/0112945602/

only the 5th subfolder changes.

I want to list all of the 5th subfolders and reorganize them like this:

/Folder1/Folder2/output01/0653/3547/0112945601/
/Folder1/Folder2/output02/0653/3547/0112945602/ 
/Folder1/Folder2/output03/0653/3547/0112945603/ 
...
/Folder1/Folder2/output<nn>/0653/3547/01129456<nn>/ 

and if we have 10 subfolders, I need to have 10 output folders, following this logic.

I tried using

find -maxdepth 5 -type d 

and put it inside a while loop but I can't work only with the 5th subfolder.

What do you think I can do?

Freddy
  • 25,565

3 Answers3

1
for dir in Folder1/Folder2/output/*/*/*; do
    suffix=${dir:(-2)}
    subdir="$(cut -d '/' -f 4- <<<$dir)"
    newdir="Folder1/Folder2/output${suffix}/${subdir}"
    echo mkdir -p "$newdir"
    echo mv "$dir"/* "$newdir"/
done

After you've dry-runned this, if it looks like it's generating the commands that will work for you, then remove the echo statements to actually move the files.

spuck
  • 306
1

Assuming you're currently located in the directory where Folder1 is located:

#!/bin/bash

Don't even attempt to do something

if we're in the wrong place.

cd Folder1/Folder2 || exit 1

Make the shell remove patterns that aren't matched,

rather than leaving them as they are.

shopt -s nullglob

for dirpath in output////; do if [[ $dirpath =~ output/(.)/[^/]*(..)/ ]]; then # "${BASH_REMATCH[1]}" is something like "0653/3457" # "${BASH_REMATCH[2]}" is the 2-character suffix, like "01"

            newdir=output${BASH_REMATCH[2]}/${BASH_REMATCH[1]}
            mkdir -p &quot;$newdir&quot; &amp;&amp;
            mv &quot;$dirpath&quot; &quot;$newdir&quot;
    fi

done

This uses the regular expression matching feature of bash to pick out the numerical suffix from the end of the directory pathname and constructs a new output directory name using this.

This would take the directory structure

.
`-- Folder1/
    `-- Folder2/
        `-- output/
            `-- 0653/
                `-- 3547/
                    |-- 0112945601/
                    `-- 0112945602/

and turn it into

.
`-- Folder1/
    `-- Folder2/
        |-- output/
        |   `-- 0653/
        |       `-- 3547/
        |-- output01/
        |   `-- 0653/
        |       `-- 3547/
        |           `-- 0112945601/
        `-- output02/
            `-- 0653/
                `-- 3547/
                    `-- 0112945602/

Empty directories in Folder1/Folder2/output could then be removed using

find Folder1/Folder2/output -type d -empty -delete

or, using standard find and ignoring errors from rmdir when it tries to remove a non-empty directory,

find Folder1/Folder2/output -depth -type d -exec rmdir {} \; 2>/dev/null

which leaves

.
`-- Folder1/
    `-- Folder2/
        |-- output01/
        |   `-- 0653/
        |       `-- 3547/
        |           `-- 0112945601/
        `-- output02/
            `-- 0653/
                `-- 3547/
                    `-- 0112945602/

You would obviously run this on a copy of your data first.

Kusalananda
  • 333,661
-1
#!/usr/bin/env bash
PATH="/folder1/folder2/folder3"
HIERARQUIA=$(/usr/bin/find $PATH/????/????/  -maxdepth 0 -type d | /usr/bin/cut -d "/" -f5-|/usr/bin/sort -s )
OUTPUT=1

for i in $HIERARQUIA
    do
        SUBPASTAS=$(/usr/bin/find $PATH/$i -maxdepth 1 -type d | /usr/bin/cut -d "/" -f7 |/usr/bin/sort -s)
        for a in $SUBPASTAS
            do
                /usr/bin/mkdir -p $PATH/output$OUTPUT/$i$a
                /usr/bin/mv $PATH/$i$a/* $PATH/output$OUTPUT/$i$a
                OUTPUT=$(($OUTPUT +1))              
            done
            OUTPUT=1
    done

I found that result, and it achieved the goal. for everyone who one day has a similar problem here is the code.

Thanks to everyone who responded and tried to help me

  • If you didn't use PATH as a variable, then you would not need to use the absolute paths to the utilities that you use. The PATH variable should be a :-delimited string of the directory paths where executables may be found. – Kusalananda Feb 11 '21 at 20:20
  • Also note that in your question you say /Folder1/Folder2/output, but it seems that you use /folder1/folder2/folder3 in your answer. Your use of find is not needed at all and it's unclear why you sort the output before looping over it (see this question). This would break if any directory path contained a whitespace character, or a filename globbing character (see also this question, and here). – Kusalananda Feb 11 '21 at 20:23
  • @ Kusalananda I use sort because my folders are number ordened ... example: $PATH/????/????/?????? is $PATH/0001/0001/000001 $PATH/0001/0001/000002 $PATH/0001/0001/000003

    and I want to work with this in order. Tnks for the tips. tnks everyone.

    – Samuel Santiago Feb 12 '21 at 14:02