How to recursively convert all JPGs into one PDF in each folder using img2pdf?
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' {} + \
Solution 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
andsecond
-
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