Bash Ham çok satırlı dize?


1

Bash yorumlanmamış bir dize almanın bir yolu var mı - tek ve ouble tırnak ve Bang! vb. ?

Gibi bir şey yapmak istiyorum

#!/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}'

Sorun şu ki sıfır STDIN: satırlar yazdırılıyor - stdin python programına aktarılmıyor.

İşte bir usecase: giriş boyutunun düşük GB'nin boyutuna sahip olabileceğini unutmayın:

kedi "my10GBfile.dat" | python -c "" ".. vb

Şimdi orada bir HEREDOC kullanarak .eg

#!/bin/bash

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

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

stdin'in kilitlenebileceği problemi var - ve böylece girdi kaybedildi.

Gerçekten istediğim, bash'deki yorumlanmamış çok satırlı dize.


Aslında yapmak istediklerinize daha yakın bir örnek verebilir misiniz, yani daha az teorik ve daha pratik bir örnek? Şu an itibariyle başarmaya çalıştığınız şeyde bir belirsizlik olduğunu görüyorum (STDIN'in kaybolduğunu söylüyorsunuz, ancak nasıl kullanılması gerektiğini göstermiyorsunuz - belirli görevler için bir geçici çözüm olabilir).
Daniel Andersson,

@Daniel, print deyimini python'un içine ekledim ve açıklamada hiçbir şey yazdırılmadı.
javadba

Doğal yolun, dosyaya doğrudan Python içinden erişmek olacağını unutmayın. Büyük olasılıkla AWK ve diğer CLI araçlarıyla yapabileceğiniz her şeyi doğrudan yerel Python içinde, muhtemelen önemli hızlanmalarla yapabilirsiniz. Kabuk güçlüdür, ancak karışımda daha eksiksiz betik dilleri atıldığında (tipik olarak Perl / Python) koşum için daha fazla güç vardır. Python fonksiyonları basitse bir diğer olasılık da AWK'yi kodda yer alacak şekilde genişletmek ve dosya adını doğrudan AWK'ya iletmektir. catBu şekilde kullanmak nadiren gitmek için "doğru" yoldur.
Daniel Andersson,

@Daniel. ilke olarak katılmıyorum. Yüzlerce-düşük K satırında python komut dosyaları var. Bazen kabuk-kabuk işlerinde kodlanmış şeyler vardır ve onları rahatsız etmek istemezler, sadece tek bir adım ekleyin ve bu da pitonu bu durumda bir seçenek haline getirir.
javadba

Yanıtlar:


3

Heredoc , yorumlanmamış bir çok satırlı dize sağlar (en azından sınırlayıcıyı belirtirseniz ); içeriğine erişmenin hiçbir (kolay) yolu yoktur.

STDIN zaten başka bir şey için kullanıldığından, heredoc içeriğini python'a iletmek için yeni bir dosya tanımlayıcısı oluşturabilirsiniz:

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

Bu benim aradığım şey olabilir: pipoları düşünüyordum ama dosya tanımlayıcısı komut dosyasının kendisi için şeffaf. Ben deneyeceğim!
javadba

harika çalışıyor thx
javadba

2

Herhangi bir şekilde fantezi almaya gerek yok: sadece tek satırlı çok satırlı alıntı:

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}'

0

Peki ya ( < <()satır satır girişleri taklit etmek için Bash yapısını kullanarak ):

$ 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")

Hangi çıktı verir:

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

Python'un iç """sözdizimini kullanarak , dizeler üç tırnak dışındaki her şeyden korunur. readBu şekilde kullanmak , Python programını her satır için bir kez çağırır. Bu, verdiğiniz örnekte işe yarar, ancak asıl göreviniz farklı olabilir (bu yüzden yorumlarda belirli bir örnek istedim). Belki de alıntı "hile" yine de yararlı olabilir.

Python hiç kullanılacaksa, tüm manipülasyonu Python kodu içinden yapmak daha kolay görünüyor; tüm yetkili bir betik dili sonra.


Yanıtınız için teşekkürler. Benim usecase yüzlerce düşük milyonlara kadar satır sayıları içerir, bu yüzden her satırda python yeniden başlatmak en uygun olmaz. Giriş, düşük GB boyutunda bir cat'ed dosyası olacaktır.
javadba

Yukarıdaki kullanım durumunu ekledim.
javadba
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.