Como executar este comando específico do shell do Python?

2

OK, tenho este script de shell não-funcional, que estou reescrevendo peça por peça em python, exceto que estou recebendo um erro "inesperado" do shell (veja abaixo):

#/bin/sh
LINES='cat $@ | wc -l'

for i in 'seq 1 $lines'; do

head -n $i $@ | tail -n 1 | text2wave -o temp.wav
sox "otherstuff.wav" "temp.wav" "silence.wav" "output.wav"
mv output.wav otherstuff.wav
rm -rf temp.wav

done

O que não é realmente viável na prática. Mas se eu souber o número de linhas em um arquivo, posso executá-lo em um arquivo específico para o arquivo inteiro do TTS e inserir 10 segundos de silêncio entre cada linha, porque não preciso dizer

LINES='cat $@ | wc -l'

No interesse do controle de fluxo, e uma maneira de incorporar a contagem de linha em um script que eu possa usar em qualquer lugar, vou usar o Python para fazer este trabalho. Até agora eu tenho esse fragmento, também não funcional:

import linecache, os

for i in range(linelength):
    lineone = linecache.getline(filename, i)
    os.system("echo " + lineone + "|" + "festival --tts")

que fornece este erro no interpretador IPython :

d 68.
sh: 2: Syntax error: "|" unexpected
Out[60]: 512
d 67.
sh: 2: Syntax error: "|" unexpected
Out[60]: 512
c 52.
sh: 2: Syntax error: "|" unexpected
Out[60]: 512
c 42.
sh: 2: Syntax error: "|" unexpected
Out[60]: 512
c 71.
sh: 2: Syntax error: "|" unexpected
Out[60]: 512
c 51.
sh: 2: Syntax error: "|" unexpected
Out[60]: 512
c 19.
sh: 2: Syntax error: "|" unexpected
Out[60]: 512
c 18.
sh: 2: Syntax error: "|" unexpected
Out[60]: 512
b 16.
sh: 2: Syntax error: "|" unexpected
Out[60]: 512
b 15.
sh: 2: Syntax error: "|" unexpected
Out[60]: 512
b 1.
sh: 2: Syntax error: "|" unexpected
Out[60]: 512
d 16.
sh: 2: Syntax error: "|" unexpected
Out[60]: 512
d 14.
sh: 2: Syntax error: "|" unexpected
Out[60]: 512
a 96.
sh: 2: Syntax error: "|" unexpected
Out[60]: 512
a 95.
sh: 2: Syntax error: "|" unexpected
Out[60]: 512
a 35.
sh: 2: Syntax error: "|" unexpected
Out[60]: 512
a 25.
sh: 2: Syntax error: "|" unexpected
Out[60]: 512
d 74.
sh: 2: Syntax error: "|" unexpected
Out[60]: 512
d 83.
sh: 2: Syntax error: "|" unexpected
Out[60]: 512
a 9.
sh: 2: Syntax error: "|" unexpected
Out[60]: 512
d 9.
sh: 2: Syntax error: "|" unexpected
Out[60]: 512
b 97.
sh: 2: Syntax error: "|" unexpected
Out[60]: 512
b 99.
sh: 2: Syntax error: "|" unexpected
Out[60]: 512
b 76.
sh: 2: Syntax error: "|" unexpected
Out[60]: 512
b 77.
sh: 2: Syntax error: "|" unexpected
Out[60]: 512
d 89.
sh: 2: Syntax error: "|" unexpected
Out[60]: 512
d 99.
sh: 2: Syntax error: "|" unexpected
Out[60]: 512
b 94.
sh: 2: Syntax error: "|" unexpected
Out[60]: 512
d 54.
sh: 2: Syntax error: "|" unexpected
Out[60]: 512
d 66.
sh: 2: Syntax error: "|" unexpected
Out[60]: 512
c 81.
sh: 2: Syntax error: "|" unexpected
Out[60]: 512
c 61.
sh: 2: Syntax error: "|" unexpected
Out[60]: 512

e que replica

for i in 'seq 1 $lines'; do

head -n $i $@ | tail -n 1 | text2wave -o temp.wav

mas é mais prático para testar tudo, porque ele simplesmente o lê ( festival e text2wave são parte do mesmo pacote, um lê as coisas e os outros escrevem arquivos) ...

agora, o número de linhas que já estão sendo recuperadas e armazenadas em linelength (não tive problema em fazer o python fazer isso):

Se fosse simplesmente

for i in range(linelength):
    lineone = linecache.getline(filename, i)
    os.system("echo somestuffnotaline | festival --tts")

então o festival diria "somEhstuffnotaLINE", mas eu não estaria tão feliz como eu diria, "c 62" - "d 74" - etc, esses são o conteúdo de cada linha nos arquivos que estou processando.

    
por ixtmixilix 29.11.2011 / 17:03

2 respostas

2

Sua pergunta é longa e desconexa e não sei o que você espera de uma resposta. Indo pelo seu título, acho que seu foco está neste fragmento de código Python:

lineone = linecache.getline(filename, i)
os.system("echo " + lineone + "|" + "festival --tts")

Seu problema é que lineone é toda a linha, incluindo a nova linha final. Você precisa, como dizem em terra Perl, chomp it .

lineone = linecache.getline(filename, i).rstrip('\n')
os.system("echo " + lineone + "|" + "festival --tts")

Seu primeiro script de shell parece muito complicado e lento para o que ele faz. Por que você está computando o número de linhas e recuperando as linhas por número em ordem? Você poderia simplesmente leia a entrada uma linha de cada vez , como você faz em Python.

while IFS= read -r line; do
  echo "$line" | text2wave -o temp.wav
  sox "otherstuff.wav" "temp.wav" "silence.wav" "output.wav"
  mv output.wav otherstuff.wav
  rm temp.wav
done

Você deve ser capaz de simplificar isso ainda mais usando arquivos de áudio brutos, que não contêm um cabeçalho e, portanto, podem ser concatenados:

while IFS= read -r line; do
  echo "$line" | text2wave -otype raw >>otherstuff.raw
  cat silence.raw >>otherstuff.raw
done
sox … otherstuff.raw otherstuff.wav

Você precisará informar sox de quais parâmetros (como profundidade de amostragem) o arquivo de áudio bruto está codificado.

    
por 30.11.2011 / 02:58
0

Sugiro usar a chamada popen() em vez de system() e gravar as linhas no fluxo de entrada.

import linecache, os
p = os.popen("festival --tts", "w")
for i in range(linelength):
    lineone = linecache.getline(filename, i)
    p.write(lineone+'\n')
p.close()

Aproveite que festival pode ter várias linhas de texto como entrada.

    
por 30.11.2011 / 04:58