将从 os.walk 收到的路径放入到 Windows 终端上的 运行 的 cmd - python
Putting a path received from os.walk into a cmd to run on Windows terminal - python
我的代码有问题,如下所示:
def optimizer(dst, directory = r"G:\Attachments\Attachments" ):
dst = " /d " + dst
reducer = '"' + r"C:\Program Files (x86)\ORPALIS\PDF Reducer 3 Professional Edition\pdfreducer.exe" + '"' + " /q 2"
for path, dirs, files in os.walk(directory):
src = r" /f " + path
cmd = reducer + src + dst
subprocess.call(cmd)
optimizer(r"C:\Users\Desktop\ReducedPdfs")
我想做的是遍历给定目录中的所有目录并使用此命令优化 pdf:
"C:\Program Files (x86)\ORPALIS\PDF Reducer 3 Professional Edition\pdfreducer.exe" /q 2 /f G:\Attachments\Attachments /d C:\Users\Desktop\ReducedPdfs
.
问题出在我在上述方法中一起解析此命令时使用的 path 变量。如果我保留它,因为它是从 os.walk 返回的,它是一个普通字符串,然后斜线被视为转义序列。如果我将它包装在 repr() 中,那么它会被放入带有前导和尾随单引号 (') 和双反斜杠的 PDF Reducer 软件中,程序不知道如何处理。
我尝试用 re.sub() 和 .replace() 将反斜杠替换为正斜杠,但无济于事。 re.sub() 似乎不能很好地处理转义字符,当我使用 .replace() 时,我的程序没有 运行。使用 repr(),它 运行s,但表示该文件不存在于目标中。
subprocess
命令最适合作为参数列表而不是长字符串,这有助于避免某些问题(例如转义序列、其中包含空格的路径、引号等)
你应该使用这样的东西(并根据你的需要进行修改):
cmd = [reducer, '/q', '2', '/f', path, '/d', dst]
subprocess.call(cmd)
请注意,如果您是这样使用它的,像 path
、dst
和 reducer
这样的路径不需要用引号括起来,即使它们中有空格,因为您已经指定它们是此列表中的单个项目。
在您的代码中应该是这样的:
def optimizer(dst, directory = r"G:\Attachments\Attachments" ):
reducer = r"C:\Program Files (x86)\ORPALIS\PDF Reducer 3 Professional Edition\pdfreducer.exe"
for path, dirs, files in os.walk(directory):
cmd = [reducer, '/q', '2', '/f', path, '/d', dst]
subprocess.call(cmd)
optimizer(r"C:\Users\Desktop\ReducedPdfs")
如果您只需要过滤掉那些包含 pdf 文件的子文件夹,请执行以下操作:
for path, dirs, files in os.walk(directory):
if any(f.endswith('.pdf') for f in files):
cmd = [reducer, '/q', '2', '/f', path, '/d', dst]
subprocess.call(cmd)
或者,没有 os.walk
的更快版本(使用 pathlib
):
from pathlib import Path
paths = {str(f.parent) for f in Path(directory).rglob('*.pdf')}
for path in paths:
cmd = [reducer, '/q', '2', '/f', path, '/d', dst]
subprocess.call(cmd)
我的代码有问题,如下所示:
def optimizer(dst, directory = r"G:\Attachments\Attachments" ):
dst = " /d " + dst
reducer = '"' + r"C:\Program Files (x86)\ORPALIS\PDF Reducer 3 Professional Edition\pdfreducer.exe" + '"' + " /q 2"
for path, dirs, files in os.walk(directory):
src = r" /f " + path
cmd = reducer + src + dst
subprocess.call(cmd)
optimizer(r"C:\Users\Desktop\ReducedPdfs")
我想做的是遍历给定目录中的所有目录并使用此命令优化 pdf:
"C:\Program Files (x86)\ORPALIS\PDF Reducer 3 Professional Edition\pdfreducer.exe" /q 2 /f G:\Attachments\Attachments /d C:\Users\Desktop\ReducedPdfs
.
问题出在我在上述方法中一起解析此命令时使用的 path 变量。如果我保留它,因为它是从 os.walk 返回的,它是一个普通字符串,然后斜线被视为转义序列。如果我将它包装在 repr() 中,那么它会被放入带有前导和尾随单引号 (') 和双反斜杠的 PDF Reducer 软件中,程序不知道如何处理。
我尝试用 re.sub() 和 .replace() 将反斜杠替换为正斜杠,但无济于事。 re.sub() 似乎不能很好地处理转义字符,当我使用 .replace() 时,我的程序没有 运行。使用 repr(),它 运行s,但表示该文件不存在于目标中。
subprocess
命令最适合作为参数列表而不是长字符串,这有助于避免某些问题(例如转义序列、其中包含空格的路径、引号等)
你应该使用这样的东西(并根据你的需要进行修改):
cmd = [reducer, '/q', '2', '/f', path, '/d', dst]
subprocess.call(cmd)
请注意,如果您是这样使用它的,像 path
、dst
和 reducer
这样的路径不需要用引号括起来,即使它们中有空格,因为您已经指定它们是此列表中的单个项目。
在您的代码中应该是这样的:
def optimizer(dst, directory = r"G:\Attachments\Attachments" ):
reducer = r"C:\Program Files (x86)\ORPALIS\PDF Reducer 3 Professional Edition\pdfreducer.exe"
for path, dirs, files in os.walk(directory):
cmd = [reducer, '/q', '2', '/f', path, '/d', dst]
subprocess.call(cmd)
optimizer(r"C:\Users\Desktop\ReducedPdfs")
如果您只需要过滤掉那些包含 pdf 文件的子文件夹,请执行以下操作:
for path, dirs, files in os.walk(directory):
if any(f.endswith('.pdf') for f in files):
cmd = [reducer, '/q', '2', '/f', path, '/d', dst]
subprocess.call(cmd)
或者,没有 os.walk
的更快版本(使用 pathlib
):
from pathlib import Path
paths = {str(f.parent) for f in Path(directory).rglob('*.pdf')}
for path in paths:
cmd = [reducer, '/q', '2', '/f', path, '/d', dst]
subprocess.call(cmd)