在 Python 中不带引号转义 Linux 路径,正确的方法

问题描述 投票:0回答:1

我在这里看到这个问题的大量答案明显不正确或部分正确,但没有考虑到小范围之外的任何差异。

这是我的路径:

"/home/user/text/Chapter 1-100"

在 bash/zsh 中,我可以点击 tab 键并正确转义这条路径,或者我可以使用:

printf '%q' "/home/user/text/Chapter 1-100"

退货:

/home/user/text/Chapter\ 1-100

这正是我所需要的,我无论如何都不能妥协,它必须以这种方式转义成为一个兼容的路径,用于将几百个文件与 ffmpeg 以 5 个为一组连接起来。Ffmpeg 只接受这种路径样式,它不接受带引号的字符串、单引号字符串、双反斜杠 '\' 或 4 个反斜杠。

问题是我无法使用 python 重新创建它。

Shlex.quote
只是引用字符串。使用:

replace(' ', r'\ ') or (' ', '\ ') or (' ', '\\ ') or (' ', '\\') or (' ', r'\\ ')

os.normpath(path)
也没有给我一个有效的路径。其中大部分要么保留空格不变,要么添加两个反斜杠,我很困惑为什么它不允许我只使用一个反斜杠。无论我尝试什么,我要么得到一个空格,要么得到两个反斜杠。

我需要文字 Unix 接受的转义路径。有谁知道我怎样才能做到这一点?

更多背景: 我编写了一个脚本,它使用 natsort 按顺序对 wav 文件进行排序(因为它们是有声读物并且需要按顺序排列)然后遍历几百个 wav 文件的列表并将它们分成 5 个一组,然后附加该组到 ffmpeg 接受的格式的文件 ex:

文件路径/to/the/file/Chapter\ 200/file.wav

所以最后我留下了编号的文本文件 1-5.txt - 6-10.txt 等。可以很容易地与 ffmpeg 一起使用来连接这些文件,以便以后处理成 mp4 文件。

此问题涉及需要正确转义的路径。 ffmpeg 不接受除了 UNIX 标准路径扩展“\”而不是“”之外的任何东西

这里要求的是代码:

#!/bin/env python3
import os
import sys
import glob
import re
import ffmpeg
from rich import print
from natsort import natsorted
import shutil
import shlex


def natsorter(list, path):
    files = glob.glob(f"{path}/*.wav")
    files = natsorted(files)
    return files


# def sorted_alphanumeric(data):
# convert = lambda text: int(text) if text.isdigit() else text.lower()
# alphanum_key = lambda key: [ convert(c) for c in re.split('([0-9]+)', key) ]
# return sorted(data, key=alphanum_key)

# this is where I start sorting wav files
# add fils to a list, sort list and create a new list
# that are lists of 5 audio files ie 1-5, 6-10 etc...
newlist = []
path = os.getcwd()
files = glob.glob(f"{path}/*.wav")
# send list of files and path of files to sort them numerically in order
# this is important for an audiobook
newlist = natsorter(files, path)

# create empty slices array
slices = []


# function to slice an array into chunks of {n}
def divide_chunks(l, n):
    # Looping until length 1
    # start at 0 (first), to the full length, n is the step
    for i in range(0, len(l), n):
        # yield is like return it creates a list object and appends stuff to it
        yield l[i : i + n]
        slices.append(l[i : i + n])


# n is the number of files to slice together in ffmpeg file
# ie "file path/to/file.wav"
n = 5
x = list(divide_chunks(newlist, n))
print("--------------------")
print("SLICES YIELD: ")
print(x)
print("--------------------")


# create concat text files for ffmpeg
def concat_list():
    # files_concat = []
    i = 1
    total = 0
    for arrays in slices:
        total += len(arrays)
        name = f"{i}-{total}.txt"
        i += len(arrays)
        file = open(name, "w")
        for items in arrays:
            items = os.path.abspath(items).replace(" ", r"\ ")
            file.write("file " + items + "\n")
        file.close()
        # files_concat.append(name) -> switched to yield :) i learned a thing
        yield name


catfiles = list(concat_list())
# catfiles = []
print(catfiles)
for x in catfiles:
    ffmpeg.input(x, f="concat", safe=0).output(
        f"{x}.wav", codec="copy"
    ).overwrite_output().run()
    catfiles.append(f"{x}.wav")


python shell path escaping
1个回答
0
投票

你不需要写转义序列。 concat 的文档说:

file
路径
要读取的文件的路径;特殊字符和空格必须用反斜杠或单引号转义。

所以只需在文件名周围加上单引号。

        for items in arrays:
            items = os.path.abspath(items)
            file.write(f"file '{items}'\n")
© www.soinside.com 2019 - 2024. All rights reserved.