我在这里看到这个问题的大量答案明显不正确或部分正确,但没有考虑到小范围之外的任何差异。
这是我的路径:
"/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")
你不需要写转义序列。 concat 的文档说:
路径file
要读取的文件的路径;特殊字符和空格必须用反斜杠或单引号转义。
所以只需在文件名周围加上单引号。
for items in arrays:
items = os.path.abspath(items)
file.write(f"file '{items}'\n")