Пожалуйста, прокрутите вниз до конца этого ответа, чтобы найти решение, которое я рекомендую для вашей конкретной проблемы c. Здесь есть некоторая предыстория для контекста и / или будущих посетителей, сталкивающихся с другими ошибками «слишком длинный список аргументов».
Системный вызов exec()
имеет ограничение размера; вы не можете передать более ARG_MAX
байтов в качестве аргументов процесса, где значение этой системной константы обычно запрашивается командой getconf ARG_MAX
в современных системах.
import glob
import subprocess
arg_max = subprocess.run(['getconf', 'ARG_MAX'],
text=True, check=True, capture_output=True
).stdout.strip()
arg_max = int(arg_max)
cmd = ['sed', '-i', '-e', 's/#/pau/g']
files = glob.glob('label_POS/label_phone_align/dump/*')
while files:
base = sum(len(x) for x in cmd) + len(cmd)
for l in range(len(files)):
base += 1 + len(files[l])
if base > arg_max:
l -= 1
break
subprocess.run(cmd + files[0:l+1], check=True)
files = files[l+1:]
Конечно, xargs
Команда уже делает именно это для вас.
import subprocess
import glob
subprocess.run(
['xargs', '-r', '-0', 'sed', '-i', '-e', 's/#/pau/g'],
input=b'\0'.join([x.encode() for x in glob.glob('label_POS/label_phone_align/dump/*') + ['']]),
check=True)
Однако в вашем случае может быть достаточно просто удалить длинный путь. Вы повторяете label_POS/label_phone_align/dump/
перед каждым именем файла в массиве аргументов.
import glob
import subprocess
import os
path = 'label_POS/label_phone_align/dump'
files = [os.path.basename(file)
for file in glob.glob(os.path.join(path, '*'))]
subprocess.run(
['sed', '-i', '-e', 's/#/pau/g', *files],
cwd=path, check=True)
В конце концов, возможно, предпочтете чисто Python решение.
import glob
import fileinput
for line in fileinput.input(glob.glob('label_POS/label_phone_align/dump/*'), inplace=True):
print(line.replace('#', 'pau'))