0

I am trying to execute a batch command in a Python script, simply showing the PDFs file name. Basically, the Python script is in a folder C:\users\me\desktop\python which should execute a command on a different folder on the desktop (C:\users\me\desktop\some-folder), which has subfolders with PDFs in it.

Here is the code:

from subprocess import call
import os

for root, dirs, files in os.walk("../some-folder"):
    for pdf_file in files:
        if pdf_file.endswith(".pdf"):
            pdf_file_path = os.path.join(root, pdf_file)
            os.chdir(root)
            call('for %%f in (*.pdf) do @echo %%f')

The result I get is "file not found".

1
  • If you are already getting the pdf names with python why are you trying to iterate them again with a cmd.exe FOR command? I don't see how this is a batch file problem. You really have no batch-file code in this question. Commented Feb 17, 2017 at 13:19

1 Answer 1

3

First, since you're activating built-in DOS commands, you'd have to set shell=True to run such commands.

Second, even with that it won't work, since double percent are reserved for scripts. In-line command require one sole %.

And third: don't use os.chdir, it's bad practice. Better use cwd option of subprocess calls, allows to locally change the directory when running the command.

That would work:

call('for %f in (*.pdf) do @echo %f',shell=True,cwd=root)

Of course this is probably an example since your command accomplishes nothing: you don't get the output back in your python script, you don't check return code...

If you want to get the list of *.pdf in python in root directory (with full path), I guess that you know

list_of_pdfs = glob.glob(os.path.join(root,"*.pdf"))

or in relative:

list_of_pdfs = [x for x os.listdir(root) if fnmatch.fnmatch(x,"*.pdf")]

but since you're in an os.walk loop, you'll get the output as many times as there are .pdf files, so it's not very performant / bad design & complexity.

For your whole conversion loop I would call the converter for each file, no need for .bat scripting, you have python!:

from subprocess import call
import os

for root, dirs, files in os.walk("../some-folder"):
    for pdf_file in files:
        if pdf_file.endswith(".pdf"):
           call([r"C:\xpdf\bin32\pdftotext","-raw",pdf_file], cwd=root)

passing arguments in a list automatically handles spaces in filenames.

Sign up to request clarification or add additional context in comments.

9 Comments

Thanks, this worked! However, when I just print the PDF file names like in the example, all PDFs appear multiple times even though they're only in the list once?
I see that you edited your answer: I indeed get the output as many times as there are .pdf files. How should I change my code to prevent this?
Do you want to just print the files or do something else?
No that was indeed just an example, I actually want to convert the PDFs to TXT. But if every file is being converted 100 times, it will be very slow. So only the 'call' command is different: call('for %f in (*.pdf) do "C:\\xpdf\\bin32\\pdftotext" -raw "%f"', shell=True, cwd=root)
Since the Python loop loops over all files, is it possible to just execute the 'call' command for that specific file instead of the entire map? I guess that would solve it.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.