0

I'm trying to find a program/script that can merge files based on the filename. Files are in 1 folder (output from PDF24 print to PDF) and names as the following example:

File name layout: YYYY-MM-DD HH-MM-SS file name.pdf

Examples:

2021-05-31 11-12-13 Microsoft Outlook - Memo Style.pdf
2021-05-31 11-12-15 Some another filename - string.pdf
2021-05-31 11-12-18 Some another filename - string.pdf
2021-05-31 11-12-25 Some another filename - string.pdf
2021-05-31 11-12-45 Some another filename - string.pdf
2021-05-31 11-13-21 Microsoft Outlook - Memo Style.pdf

What I want is that the program looks at the filename, and takes every file from 'Microsoft Outlook' (including Outlook) until the next 'Microsoft Outlook' (excluding) and merges them.

What I'm doing is I'm printing an Outlook file and (some of) its attachments, and I want to merge them, so every PDF file is a mail on page 1, and has its attachments on the following pages.

Requirements:

  • Important here is that the attachments are in the correct order, ie ordered by date, oldest first
  • I want the PDF files to be split by mail. Every PDF file after merging is 1 file and its attachments
  • I actually prefer a manual script because it has to run about once a week or once every few days
  • Output should be automatically saved to a folder I choose (a subfolder of the source folder)
  • I don't really care about output file names. They can be 001, 002, ... for example

I've looked at PDFtk after finding some questions on here, but it either can't do it, or I don't understand the documentation well enough (a very real possibility).

If anyone can help, it would be greatly appreciated.

PS: Merging every single PDF in 1 giant file is something I can do already, but I'd like them split because I can print and staple them automatically that way. Call me... energy efficient. Merging first and splitting afterward could be a possibility too I guess.

3
  • 1
    What program would you use to merge them all in one file?. Can it be called from the terminal? – ComputerUser121212 May 31 at 18:33
  • 1
    @ComputerUser121212 PDFtk (from the tags/original question) can merge PDF documents from the command line (whether or not they are currently using it). – Anaksunaman Jun 1 at 0:06
  • To merge al docs in 1 file, I'd use Foxit PhantomPDF or PDF24. They cannot be called from terminal afaik. I could try and use PDFtk indeed to do this, but I'd still have to figure out how to split afterwards based on content if I try to merge all first and split afterwards. Or figure out how to merge on file name. – Juno Jun 1 at 13:50
1

For future reference, the code ComputerUser121212 posted works perfectly.

I've made it into a batch file, using the following link as help: https://stackoverflow.com/questions/4571244/creating-a-bat-file-for-python-script

I'm not proficient in batch files so my code may be suboptimal, but it works.

    @echo on
rem = """

python -x "%~f0" %*
echo some more batch commands
goto :eof

"""
# Anything here is interpreted by Python

import os

files = os.listdir(".")
files.sort()

command_prefix = "pdftk "
command_args = ""
command_end = "cat output output1.pdf"
counter = 0

for file in files:
  if ".py" not in file:
    if "Microsoft Outlook" in file:
      if files.index(file) != 0:
        os.system(command_prefix + command_args + command_end)
      counter = counter + 1
      command_args = '"' + file + '"' + " "
      command_end = "cat output output" + str(counter) + ".pdf"
    else:
      command_args = command_args + '"' + file + '"' + " "

os.system(command_prefix + command_args + command_end)

Paste the code above in a Notepad, save as a .bat file inside the pdf folder, and done.

0
1

The following Python code should do the trick. The code runs on Python 3.9 and uses PDFtk. It assumes the first file in your directory is one that contains "Microsoft Outlook"

import os

files = os.listdir(".")
files.sort()

command_prefix = "pdftk "
command_args = ""
command_end = "cat output output1.pdf"
counter = 0

for file in files:
  if ".py" not in file:
    if "Microsoft Outlook" in file:
      if files.index(file) != 0:
        os.system(command_prefix + command_args + command_end)
      counter = counter + 1
      command_args = '"' + file + '"' + " "
      command_end = "cat output output" + str(counter) + ".pdf"
    else:
      command_args = command_args + '"' + file + '"' + " "

os.system(command_prefix + command_args + command_end)

Save it to a file and run it from within the same directory as your files

13
  • I'll try that first thing tomorrow. Thank you so much! – Juno Jun 3 at 22:15
  • Hi, I tried your script, but it doesn't seem to work perfecly. I named the file _com.py, and it gave the following output: V:\>python _com.py Error: Unable to find file. Error: Failed to open PDF file: zzz.py Errors encountered. No output created. Done. Input errors, so no output created. I renamed the file to zzz.py, as per your comment about the first file having to be an Outlook print, but the same thing happened. I DID get output, but the output1.pdf was missing its Outlook print. The 2nd one was correctn and there should have been a 3rd one, but that didn't show up. – Juno Jun 7 at 14:40
  • To add a general remark: it also has trouble with subfolders, though I can mitigate this by moving the subfolder. Which i did before above testing. – Juno Jun 7 at 14:46
  • @Juno Thank you for your coments. I'm sorry, for I had made some mistakes. The code should work now, assuming no subdirectories and that the first file is one that contains "Microsoft Outlook" (excluding the python script). Let me know if you have any other issues – ComputerUser121212 Jun 8 at 13:29
  • That works like a CHARM! I'm eternally grateful to you! – Juno Jun 9 at 8:15
0

One alternative to using a pure bat to do the same job...

@echo off 

Setlocal EnabledelayeDexpansion

set "_in_dir=Full\Path\To\your\pdf\Files\Folder"
set "_out_dir=Full\Path\To\Some\Temp\Folder\Output"

2>nul mkdir "!_out_dir!" & cd /d "!_in_dir!"
set _cnt=<nul & set "_results=!_in_dir!\output.pdf" 

for /f tokens^=* %%i in ('dir /od /a:a /b "*Microsoft?Outlook*.pdf"
')do set /a "_cnt+=1" && call %:^) "%%~fi" "000!_cnt!" "!_out_dir!"

pushd "Full\Path\To\your\pdfTK\Folder\bin"
pdftk.exe "!_out_dir!\*.pdf" cat output "!_results!"

%:^) 
if not "%~nx1"=="" (set "_new=%~2" & call move "%~1" "%~3\!_new:~-4!.pdf"
     exit /b) else (rmdir /s /q "!_out_dir!\." & popd & endlocal & goto :eOf)

1) Edite this script for add/set the variables to their respective paths that you will use in the bat process and also the pertinent full path to pdfTK.exe folder:

set "_in_dir=Full\Path\To\your\pdf\Files\Folder"
set "_out_dir=Full\Path\To\Some\Temp\Folder\Output"
...
pushd "Full\Path\To\your\pdfTK\Folder\bin"

2) List your files by filtering the names of interest, already in order by date (old first) in one for /f loop:

dir /od /a:a /b 

3) For each looped file, increment a counter to do inside a function already passing the pdf file path "!_in_dir!\%%~i %%~j %%~k"and the temporary folder "!_out_dir!\." :

set /a "_cnt+=1" && call %:^) "%%~fi" "000!_cnt!" "!_out_dir!"

4) Your function :label %:^) will rename the files in numerical order to make it possible to concatenate by date order already move the file to its temporary folder in processing:

%:^)
...
set "_new=%~2" & call move "%~1" "%~3\!_new:~-4!.pdf"

5) After ending the loop in the pdf files, your temporary folder already contains the files of interest, so run pdftk to concatenate already saving/generating the desired file:

pushd "Full\Path\To\your\pdfTK\Folder\bin"
pdftk.exe "!_out_dir!\*.pdf" cat output "!_results!"

6) When in execution/processing you reach the if line, after finishing the for /f loop, your bat will remove the created folder and exit/close execution...

if not "%~nx1"=="" (...
     ) else (rmdir /s /q "!_out_dir!\." & popd & endlocal & goto :eOf)

Additional Resources:

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.