1

I have this folder-strucutre, with really heavy high-quality images in each subfolder

tree -d ./

Output:

./
├── 1_2dia-pedro
├── 3dia-pedro
│   ├── 101MSDCF
│   └── 102MSDCF
├── 4dia-pedro
└── Wagner
    ├── 410_0601
    ├── 411_0701
    ├── 412_0801
    ├── 413_2101
    ├── 414_2801
    ├── 415_0802
    ├── 416_0902
    ├── 417_1502
    ├── 418_1602
    ├── 419_1702
    ├── 420_2502
    └── 421_0103

18 directories

And, I want to compress it, just like I would do with ffmpeg, or imagemagick. e.g.,

ffmpeg -i %%F -q:v 10 processed/%%F"
mogrify -quality 3 $F.png

I'm currently think of creating a vector of the directories, using shopt, as discussed here

shopt -s globstar dotglob nullglob
printf '%q\n' **/*/

Then, create a new folder-compressed, with the same structure

mkdir folder-compressed
<<iterate the array-vector-out-of-shopt>>

Finally, compress, for each subfolder, something in the lines of

mkdir processed
for f in *.jpg;
    do ffmpeg -i "$f" -q:v 1 processed/"${f%.jpg}.jpg"; 
done

Also, I read this question, and this procedure seems close to what I would like,

for f in mydir/**/*
do
  # operations here
done

Major problem: I'm bash newbie. I know all tools needed are at my disposal!

EDIT: There is a program that, for the particular purpose of compressing images with lossless quality, gives us a a-liner, and a lot of options to this compression. The caveat: make another copy of the original folder-structure-files, because it will change them permanently in the folder-structure-files you give it.

cp -r ./<folder-structure-files> ./<folder-structure-files-copy>
image_optim -r ./<folder-structure-files-copy>

I think @m0hithreddy solution is pretty cool, though. Certainly, I will be using that logic elsewhere anytime soon.

BuddhiLW
  • 608
  • 3
  • 9
  • You're mixing bash and batch syntax here. Which language do you want to do this in? And, if your directory looks like that, you don't need recursion. – oguz ismail May 23 '21 at 12:48
  • It's in bash, uniquely. I edited the post, to make that explicit. Thanks. About the need for recursion: I will run the script on the top level of a folder, which has 5 other subfolders, which some of them have subsubfolders. So, I think recursion is a perfect fit - I want the behavior similar to $(cp -r). Of course, in this case I'm applying a compression, not only copying the files – BuddhiLW May 23 '21 at 13:39

1 Answers1

1

Instead of pre-mkdiring directories, you can create the required directories on the fly. Recursion solutions look elegant to me then compared to loops. Here is a straight-forward approach. I echoed the file names and directories to keep track of whats going on. I am not ffmpeg pro, I used cp instead but should work fine for your use case.

Shell script:

source=original/ 
destination=compressed/

f1() {
    mkdir -p ${destination}${1}
    
    for file in `ls ${source}${1}*.jpg 2>/dev/null` 
    do
        echo 'Original Path:' ${file}
        echo 'Compressed Path:' ${destination}${1}$(basename $file) '\n'
        cp ${file} ${destination}${1}$(basename $file)
    done

    for dir in `ls -d ${source}${1}*/ 2>/dev/null`
    do
        echo 'Enter sub-directory:' ${dir} '\n'
        f1 ${dir#*/}
    done
}

f1 ''

Terminal Session:

$ ls 
original  script.sh
$ tree original/
original/
├── f1
│   ├── f16
│   │   └── f12.jpg
│   ├── f5
│   │   └── t4.jpg
│   └── t3.txt
├── f2
│   └── t5.txt
├── f3
├── f4
│   └── f10
│       ├── f2
│       │   └── f6.jpg
│       └── f3.jpg
├── t1.jpg
└── t2.txt

8 directories, 8 files
$ sh script.sh 
Original Path: original/t1.jpg
Compressed Path: compressed/t1.jpg 

Enter sub-directory: original/f1/ 

Enter sub-directory: original/f1/f16/ 

Original Path: original/f1/f16/f12.jpg
Compressed Path: compressed/f1/f16/f12.jpg 

Enter sub-directory: original/f1/f5/ 

Original Path: original/f1/f5/t4.jpg
Compressed Path: compressed/f1/f5/t4.jpg 

Enter sub-directory: original/f2/ 

Enter sub-directory: original/f3/ 

Enter sub-directory: original/f4/ 

Enter sub-directory: original/f4/f10/ 

Original Path: original/f4/f10/f3.jpg
Compressed Path: compressed/f4/f10/f3.jpg 

Enter sub-directory: original/f4/f10/f2/ 

Original Path: original/f4/f10/f2/f6.jpg
Compressed Path: compressed/f4/f10/f2/f6.jpg 

$ tree compressed/
compressed/
├── f1
│   ├── f16
│   │   └── f12.jpg
│   └── f5
│       └── t4.jpg
├── f2
├── f3
├── f4
│   └── f10
│       ├── f2
│       │   └── f6.jpg
│       └── f3.jpg
└── t1.jpg

8 directories, 5 files
m0hithreddy
  • 1,752
  • 1
  • 10
  • 17
  • 1
    Amazing, M0hithreddy! Thank you. That was very elegant and general solution, indeed! At the same time, very concise and semantic. – BuddhiLW May 23 '21 at 16:37