2

I have three levels of folders like main, sub-1 and sub-2. my main folder has lot of sub-1 folders and sub-1 has lot of sub-2 folder with JPG images inside.

I copy JPG files from sub-2 to its parent sub-1 folder FROM main folder by using this command.

find . -type f -name "*.jpg" -exec sh -c 'for p; do
  cp "$p" "${p%/*/*}"
done' _ {} +

Now I have to convert all jpgs into one pdf file inside each sub-1 folder from my MAIN folder, so there will be my all copied jpgs along with converted pdf in sub-1 (pdf name should be the folder name ex: sub-1). after convert finished I have to delete the copied jpgs only inside sub-1 folder (not original jpgs), so there will be many sub-2 folders with a single pdf file.

I am using img2pdf library to covert my images. and I tried this command below it does not do the work, I could not find any solution. Now how do I make this works?

find . -name '*.jpg' -type f -exec bash -c 'img2pdf *.jpg -o "${PWD##*/}".pdf' {} + \
3
  • Using single quotes ' will probably not let the ${...} expand as intended. I think you need not wrap the 'imp2pdf command line' in bash -c ' ...'
    – sudodus
    Aug 31 at 9:52
  • I tried still not working
    – Sam
    Aug 31 at 10:19
  • OK. I had to check the details by testing. See the answer below.
    – sudodus
    Aug 31 at 11:29
1

I did some tests in my Photos directory tree, and the following system with two shellscripts works for me.

first:

#!/bin/bash

find * -type d -exec second {} \;
echo ""

second:

#!/bin/bash

num=$(ls "$1"/*.jpg 2> /dev/null | wc -l)
if [ $num -ne 0 ]
then
 echo -n "."
 img2pdf -o "$1/${1//\//-}_${num}_pictures".pdf "$1"/*.jpg
fi

Edit twice: Alternate script second makes a pdf file without number of pictures and 'pictures' in the name:

#!/bin/bash

num=$(ls "$1"/*.jpg 2> /dev/null | wc -l)
if [ $num -ne 0 ]
then
 echo -n "."
 img2pdf -o "$1/${1##*/}".pdf "$1"/*.jpg
fi
  • Copy and paste from the code areas into a text editor and create the files first and second

  • Make them executable

    chmod +x first second
    
  • move them to a directory in PATH. If this is only for your personal use, [create and] move them in into ~/bin. Otherwise if other users should also use these shellscripts, move them into /usr/local/bin

    mkdir ~/bin
    mv first second ~/bin
    

    You may need to reboot to get ~/bin into your PATH.

Now you are ready to use them. Change directory to the top or the directory tree, where you have your pictures and run first.

Example (but you have local names, not Pictures like the English),

cd ~/Pictures
first

It will write a dot to the terminal window for each subdirectory where it finds at least one picture and creates a pdf file.

The you can find the pdf files with the following command

find -name "*.pdf"

Major edit:

After a discussion with the original poster, I think I understood the structure of the directory tree to be processed. Copies of the files at lower levels are located in the sub-1 directories with person's names. The files in these sub-1 directories are to be merged into pdf-files.

Example:

$ tree -U
.
├── adam
│   ├── mkusb-minp-2-crop.jpg
│   ├── us_keyboard_for_sudo_password.jpg
│   ├── nautilus-connect-to-server-2.jpg
│   ├── pict1
│   │   ├── mkusb-minp-2-crop.jpg
│   │   └── nautilus-connect-to-server-2.jpg
│   ├── pict2
│   │   └── us_keyboard_for_sudo_password.jpg
│   └── adam.pdf
└── betty
    ├── nautilus-connect-to-server-1.jpg
    ├── mkusb-minp-3-cropx.jpg
    ├── pict1
    │   ├── nautilus-connect-to-server-1.jpg
    │   └── calamares-mount-failed.jpg
    ├── pict2
    │   └── mkusb-minp-3-cropx.jpg
    ├── calamares-mount-failed.jpg
    └── betty.pdf

6 directories, 14 files

If you change working directory with cd to where these name-directories are located, you can use the following modified first shellscript.

#!/bin/bash

find -mindepth 1 -maxdepth 1 -type d -exec second {} \;
echo ""

It will run the second shellscript only in the name-directories and not look for what is in [upper or] lower levels of the directory tree.

The following shows how find finds only the name-directories

$ find -mindepth 1 -maxdepth 1
./adam
./betty
8
  • If you have file names with spaces, there will probably be problems. One solution can be to but the command with img2pdf into a small second [shellscript] file and call the shellscript in the command line with find. This way you can have double quotes around the files: "*.jpg" in the small second shellscript. An alterniative is the replace the spaces with underscores: "filename with spaces" --> "filename_with_underscores".
    – sudodus
    Aug 31 at 11:41
  • I tried your script, it is creating empty pdfs in each directories with wrong names, my folder name in Arabic
    – Sam
    Sep 1 at 5:15
  • It works for me with a non-English western European language. It is possible that you have a problem because of the folder names or file names. I suggest that you create a second [shellscript] file and make it work for a single directory. Then make the first [master shellscript] file with find that calls the second shellscript for each subdirectory containing files. Can you do that yourself or do you need help with it? (You may need help from someone using the same language.)
    – sudodus
    Sep 1 at 6:25
  • I am totally new to this scripts sir, I think might need help
    – Sam
    Sep 1 at 6:31
  • OK @Looper, I added details how to make system with two scripts,where first calls second for each subdirectory. This works for me, and I hope that it works with Arabic too. If not you need help from someone else, who knows Arabic and/or who knows better how to manage special characters in file names.
    – sudodus
    Sep 1 at 8:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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