Cadeia de caracteres multilinhas em bruto no bash?

1

Existe uma maneira de obter uma string não interpretada no bash - pode incluir aspas simples e simples e Bang! etc?

Eu quero fazer algo como

#!/bin/bash

echo -e "Line One\nLine Two\nLine three" | python -c """
import sys
for line in sys.stdin.readlines():
  print "STDIN: %s" %line
""" | awk '{print $2}'

O problema é que zero STDIN: linhas são impressas - stdin não está sendo canalizado para o programa python.

Aqui está uma usecase: note que o tamanho da entrada pode ter o tamanho baixo de GB:

cat "my10GBfile.dat" | python -c "" ".. etc

Agora usando um HEREDOC lá .e.g.

#!/bin/bash

echo -e "Line One\nLine Two\nLine three" | python<<-HERE
some

multiline
python 
program
HERE
| awk '{print $2}'

tem problema que o stdin é cooptado - e assim a entrada é perdida.

O que eu realmente quero é essa sequência multilinha não interpretada no bash.

    
por javadba 13.06.2013 / 22:44

3 respostas

3

O heredoc faz fornecer uma cadeia multilinha não interpretada (pelo menos se você citar o delimitador); simplesmente não há maneira (fácil) de acessar seu conteúdo.

Como o STDIN já está sendo usado para outra coisa, você pode criar um novo descritor de arquivo para passar o conteúdo do heredoc para python:

exec 3<<'HERE'
import sys
print "Line Zero!\n"
for line in sys.stdin:
    print line
HERE
echo -e "Line One\nLine Two\nLine Three" | python /dev/fd/3
    
por 14.06.2013 / 00:14
1

Não há necessidade de se fantasiar de forma alguma: apenas cite uma string multilinha:

echo -e "Line One\nLine Two\nLine three" | python -c '
  import sys
  for line in sys.stdin.readlines():
    print "STDIN: %s" %line
' | awk '{print $2}'
    
por 14.06.2013 / 01:52
0

Que tal (usando a construção < <() Bash para emular a entrada linha por linha):

$ while read i; do echo -e '
#this is a multiline python program
if True:
    print """line: '"$i"'"""
' | python | awk '{print $0, "→", $3}'; done < <(echo -e "Line One\nLine Two\nLine Three")

que dá saída:

line: Line One → One
line: Line Two → Two
line: Line Three → Three

Usando a sintaxe """ interna do Python, as sequências serão protegidas de tudo, exceto três citações. Usar read desta maneira invocará o programa Python uma vez para cada linha. Isso funciona no exemplo que você deu, mas sua tarefa real pode ser diferente (e é por isso que pedi um exemplo específico nos comentários). Talvez o "truque" de citação possa ser útil de qualquer maneira.

Se o Python for usado, parece mais fácil fazer toda a manipulação a partir do código Python; afinal, é uma linguagem de script competente.

    
por 13.06.2013 / 23:54

Tags