Tek satırlı komut satırında çok satırlı deyimler yürütülüyor mu?


198

Python ile -cbir satırlık döngü, yani yürütmek için kullanıyorum :

$ python -c "for r in range(10): print 'rob'"

Bu iyi çalışıyor. Ancak, for döngüsü önce bir modül alırsanız, bir sözdizimi hatası alıyorum:

$ python -c "import sys; for r in range(10): print 'rob'"
  File "<string>", line 1
    import sys; for r in range(10): print 'rob'
              ^
SyntaxError: invalid syntax

Bunun nasıl düzeltilebileceği hakkında bir fikrin var mı?

Bunu Makefile'a dahil edebilmem için tek astar olarak benim için önemli.


Bu sorunuza cevap veriyor mu?
Yürütülecek

Yanıtlar:


182

yapabilirsin

echo -e "import sys\nfor r in range(10): print 'rob'" | python

veya boruları hariç:

python -c "exec(\"import sys\nfor r in range(10): print 'rob'\")"

veya

(echo "import sys" ; echo "for r in range(10): print 'rob'") | python

veya @ SilentGhost'un cevabı / @ Crast'ın cevabı


Son seçenek Windows'da python3 ile harika çalışıyor
Ian Ellis

1
@RudolfOlah şimdiye kadar biliyorsunuz ama sadece referans için, python3 + sürümleri için yazdırma ifadesini sarmanız gerekiyor:python -c "exec(\"import sys\nfor r in range(10): print('rob')\")"
systrigger

@systrigger teşekkürler, ben acele olduğunu düşünüyorum ve heh olduğunu fark etmedi

89

bu stil makyaj dosyalarında da kullanılabilir (ve aslında oldukça sık kullanılır).

python - <<EOF
import sys
for r in range(3): print 'rob'
EOF

veya

python - <<-EOF
    import sys
    for r in range(3): print 'rob'
EOF

ikinci durumda, önde gelen sekme karakterleri de kaldırılır (ve bazı yapılandırılmış görünüm elde edilebilir)

EOF yerine, burada belgede görünmeyen herhangi bir işaret sözcüğü bir satırın başında durabilir (ayrıca bkz. burada bash manpage veya burada bulunan belgeler ).


9
Güzel. Ayrıca , argümanları iletmek için basitçe sonra yerleştirin <<EOF. Not, bu daha iyidir ancak, o alıntı sınırlayıcı - örneğin <<'EOF'- içeriğini korumak için böylece burada doküman üzerinde yukarı-cepheden kabuk açılımları.
mklement0

56

Sorun aslında import deyimi ile değil, for döngüsünden önce olan herhangi bir şeyle ilgili. Veya daha spesifik olarak, satır içi bloktan önce görünen herhangi bir şey.

Örneğin, bunların hepsi işe yarar:

python -c "import sys; print 'rob'"
python -c "import sys; sys.stdout.write('rob\n')"

İçe aktarma ifadesi olmak bir sorun olsaydı, bu işe yarardı, ancak işe yaramaz:

python -c "__import__('sys'); for r in range(10): print 'rob'"

Çok temel örneğiniz için, bunu şu şekilde yeniden yazabilirsiniz:

python -c "import sys; map(lambda x: sys.stdout.write('rob%d\n' % x), range(10))"

Bununla birlikte, lambdas deyimleri veya birden çok deyimi değil, yalnızca ifadeleri yürütebilir, bu nedenle yapmak istediğiniz şeyi yapmaya devam edemeyebilirsiniz. Bununla birlikte, jeneratör ifadeleri, liste anlama, lambdas, sys.stdout.write, "map" yerleşimi ve bazı yaratıcı dize enterpolasyonu arasında bazı güçlü tek katmanlar yapabilirsiniz.

Soru şu ki, ne kadar ileri gitmek istiyorsunuz ve hangi noktada .pymakefile'ınızın yürüttüğü küçük bir dosya yazmak daha iyi değil?


31


- Bu cevabın Python 3.x ile de çalışmasını sağlamak printiçin fonksiyon olarak adlandırılır : 3.x'te sadece print('foo') çalışır, 2.x de kabul eder print 'foo'.
- Windows'u içeren platformlar arası bir perspektif için kxr'nin faydalı cevabına bakın .

İçinde bash, kshveyazsh :

Dize geçirilmeden önce gerçek yeni satırlara genişletilen yeni satırları göstermek için kullanılmasına izin veren bir ANSI C tırnaklı dize ( $'...') \nkullanın python:

python -c $'import sys\nfor r in range(10): print("rob")'

Not \narasında importve forsatır sonu etkileyecek ifadeleri.

To kabuk değişken değerleri geçmesi böyle bir komuta, bu kullanım için güvenli olduğu argümanlar ve üzerinden erişim onları sys.argvPython komut içi:

name='rob' # value to pass to the Python script
python -c $'import sys\nfor r in range(10): print(sys.argv[1])' "$name"

Gömülü kabuk değişkeni başvuruları olan (kaçış dizisi önceden işlenmiş) çift ​​tırnaklı komut dizesi kullanmanın artıları ve eksileri hakkında bir tartışma için aşağıya bakın .

$'...'Dizelerle güvenli çalışmak için :

  • Orijinal kaynak kodunuzdaki iki\ örnek .
    • \<char>dizileri gibi - \nbu durumda, aynı zamanda gibi olağan şüpheli \t, \r, \b- tarafından genişletilir $'...'(bakınız man printfdesteklenen kaçaklar için)
  • 'Örneklerden kaçış olarak \'.

POSIX uyumlu kalmanız gerekiyorsa :

Komut ikamesiprintf ile kullanın :

python -c "$(printf %b 'import sys\nfor r in range(10): print("rob")')"

Bu tür dizelerle güvenle çalışmak için:

  • Orijinal kaynak kodunuzdaki iki\ örnek .
    • \<char>gibi - diziler \nbu durumda, aynı zamanda gibi olağan şüpheliler \t, \r, \b- genleştirilirler printf(bkz man printfdesteklenen kaçış dizileri için).
  • Bir geçirin tek tırnaklı dize printf %bve olarak gömülü tek tırnak kaçış '\'' (sic).

    • Tek tırnak işareti kullanmak, dizenin içeriğini kabuk tarafından yorumlanmaya karşı korur .

      • Bununla birlikte, kısa Python komut dosyaları için (bu durumda olduğu gibi) kabuk değişken değerlerini komut dosyalarınıza dahil etmek için çift tırnaklı bir dize kullanabilirsiniz - ilişkili tuzakların farkında olduğunuz sürece (bir sonraki noktaya bakın); örneğin, kabuk $HOMEgeçerli kullanıcının ana dizinine genişler . aşağıdaki komutta:

        • python -c "$(printf %b "import sys\nfor r in range(10): print('rob is $HOME')")"
      • Bununla birlikte, genel olarak tercih edilen yaklaşım, kabuktan değerleri bağımsız değişkenler aracılığıyla iletmek ve bunlara sys.argvPython'dan erişmektir ; yukarıdaki komutun eşdeğeri:

        • python -c "$(printf %b 'import sys\nfor r in range(10): print("rob is " + sys.argv[1])')" "$HOME"
    • Bir kullanırken çift tırnaklı dize daha rahat Eğer gibi çift tırnak çıkış kullanılmayan tek tırnak gömülü ve gömülü kullanmasını sağlar - \"- o da yorumlamasına dize konu yapar kabuk veya niyet olabilir veya olmayabilir; $ve `kabuk anlamına gelmez kaynak kodunda karakterler bir sözdizimi hatası neden veya beklenmedik dize değiştirebilir.

      • Ek olarak, kabuğun \çift ​​tırnaklı dizgilerdeki kendi işlemesi engel olabilir; örneğin, Python'un değişmez çıktılar üretmesini sağlamak için çıktıya ro\bgeçmeniz gerekir ro\\b; Bir ile '...'kabuk dize ve iki katına \ durumlarda, elde ederiz:
        python -c "$(printf %b 'import sys\nprint("ro\\\\bs")')" # ok: 'ro\bs'
        Tam tersine, bunu yapar değil bir ile amaçlandığı gibi çalışmasını "..."kabuk dize:
        python -c "$(printf %b "import sys\nprint('ro\\\\bs')")" # !! INCORRECT: 'rs'
        kabuk yorumlayıp hem "\b" ve "\\b"edebi olarak \bek bir baş döndürücü sayıda gerektiren \istenen etkiyi elde etmek için örnekleri:
        python -c "$(printf %b "import sys\nprint('ro\\\\\\\\bs')")"

To yoluyla kodu geçmesistdin yerine -c:

Not: Burada tek hatlı çözümlere odaklanıyorum ; xorho cevabı çok hattını nasıl kullanılacağını gösterir burada-belge - emin olun alıntı Ancak sınırlayıcı; örneğin, <<'EOF'kabuğun açıkça dizeyi yukarı doğru genişletmesini istemiyorsanız (yukarıda belirtilen uyarılarla birlikte gelir).


İçinde bash, kshveyazsh :

Bir birleştirin ANSI C-alıntılanan dize ( $'...'bir) ile burada-string ( <<<...):

python - <<<$'import sys\nfor r in range(10): print("rob")'

-pythonaçıkça stdin'den okumasını söyler (varsayılan olarak yapar). -bu durumda isteğe bağlıdır, ancak komut dosyalarına da argümanlar iletmek istiyorsanız , argümanı bir komut dosyası dosya adından ayırmak için buna ihtiyacınız vardır:

python - 'rob' <<<$'import sys\nfor r in range(10): print(sys.argv[1])'

POSIX uyumlu kalmanız gerekiyorsa :

printfYukarıdaki gibi kullanın , ancak çıkışını stdin üzerinden geçirmek için bir boru hattı ile kullanın :

printf %b 'import sys\nfor r in range(10): print("rob")' | python

Bir argümanla:

printf %b 'import sys\nfor r in range(10): print(sys.argv[1])' | python - 'rob'

2
Bu seçilen cevap olmalı!
debuti

1
Bu da işe yarar ve tam bir açıklama içerdiğinden , muhtemelen en iyi cevaptır bravo!

23

Bunun nasıl düzeltilebileceği hakkında bir fikrin var mı?

Sorununuz, birbirinden ayrı Python deyimlerinin ;yalnızca tek satır olan "küçük deyimler" olmasına izin verilmesiyle ortaya çıkar. Python belgelerindeki dilbilgisi dosyasından :

stmt: simple_stmt | compound_stmt
simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
             import_stmt | global_stmt | nonlocal_stmt | assert_stmt)

Bileşik ifadeler, noktalı virgüllerle diğer ifadelerle aynı satıra dahil edilemez; bu nedenle, bunu -cbayrakla yapmak çok zor hale gelir.

Bir bash kabuğu ortamındayken Python'u gösterirken, bileşik ifadeleri eklemenin çok yararlı olduğunu düşünüyorum. Bunu güvenilir bir şekilde yapmanın tek basit yolu heredocs (posix shell şey).

Yorumlu metinler

Bir kullan yorumlu metin (ile oluşturulan <<) ve Python'un komut satırı arayüzü seçeneği , -:

$ python - <<-"EOF"
        import sys                    # 1 tab indent
        for r in range(10):           # 1 tab indent
            print('rob')              # 1 tab indent and 4 spaces
EOF

Ekleme -sonra <<( <<-) kullanmak için izin verir sekmeler (Bunu vurgulamak 8 boşluk girintili ettik böylece Stackoverflow, boşluk sekmeleri dönüştürür) bendine yapılan. Baştaki sekmeler çıkarılır.

Sadece sekmeler olmadan yapabilirsiniz <<:

$ python - << "EOF"
import sys
for r in range(10):
    print('rob')
EOF

Tırnak işareti koymak parametre ve aritmetik genişlemeyiEOF engeller . Bu, yorumlu yazılımı daha sağlam hale getirir.

Bash çok çizgili dizeler

Çift tırnak kullanırsanız, kabuk genişletme elde edersiniz:

$ python -c "
> import sys
> for p in '$PATH'.split(':'):
>     print(p)
> "
/usr/sbin
/usr/bin
/sbin
/bin
...

Kabuk genişlemesini önlemek için tek tırnak kullanın:

$ python -c '
> import sys
> for p in "$PATH".split(":"):
>     print(p)
> '
$PATH

Python'daki değişmez değerlerde tırnak işaretlerini değiştirmemiz gerektiğini unutmayın - temel olarak BASH tarafından yorumlanan tırnak işareti karakterini kullanamayız. Python'da olduğu gibi onları değiştirebiliriz - ama bu zaten oldukça kafa karıştırıcı görünüyor, bu yüzden bunu önermiyorum:

$ python -c '
import sys
for p in "'"$PATH"'".split(":"):
    print(p)
'
/usr/sbin
/usr/bin
/sbin
/bin
...

Kabul edilen cevabın (ve diğerlerinin) eleştirisi

Bu çok okunabilir değil:

echo -e "import sys\nfor r in range(10): print 'rob'" | python

Çok okunabilir değil ve ayrıca bir hata durumunda hata ayıklamak zor:

python -c "exec(\"import sys\\nfor r in range(10): print 'rob'\")"

Belki biraz daha okunabilir, ancak yine de oldukça çirkin:

(echo "import sys" ; echo "for r in range(10): print 'rob'") | python

Python'unuz varsa kötü bir zaman geçireceksiniz ":

$ python -c "import sys
> for r in range(10): print 'rob'"

mapDöngüler almak için kötüye kullanmayın veya anlama yönlerini listelemeyin:

python -c "import sys; map(lambda x: sys.stdout.write('rob%d\n' % x), range(10))"

Bunların hepsi üzgün ve kötü. Onları yapma.


3
Gramer bilgisi için ++; (genişlemeyen) burada-doc kullanışlı ve en sağlam çözümdür, ancak açıkçası bir astar değildir. Tek satırlık bir çözüm gerekiyorsa, ANSI C tırnaklı bir dize ( bash, kshveya zsh) kullanmak makul bir çözümdür: python -c $'import sys\nfor r in range(10): print(\'rob\')'(yalnızca tek tırnaklardan kaçmak konusunda endişelenmeniz gerekir (çift tırnak kullanarak kaçınabilirsiniz) ve ters eğik).
mklement0

14

return'i kullanın ve sonraki satıra yazın:

user@host:~$ python -c "import sys
> for r in range(10): print 'rob'"
rob
rob
...

6
Cidden, eğer bunu yapmaya devam edersen bir şey burkacaksın. python $(srcdir)/myscript.pybüyük adalet için.
Jason Orendorff

10

$ python2.6 -c "import sys; [sys.stdout.write('rob\n') for r in range(10)]"

İyi çalışıyor. For döngünüzü satır içine almak için "[]" kullanın.


8

Sorun importifadede değil . Sorun, kontrol akış deyimlerinin bir python komutunda satır içi çalışmadığıdır. Bu importifadeyi başka herhangi bir ifadeyle değiştirdiğinizde aynı sorunu görürsünüz.

Bir düşünün: python muhtemelen her şeyi satır içi yapamaz. Kontrol akışını gruplamak için girinti kullanır.


7

Sisteminiz Posix.2 uyumluysa printfyardımcı programı sağlamalıdır :

$ printf "print 'zap'\nfor r in range(3): print 'rob'" | python
zap
rob
rob
rob

2
İyi bir çözüm, ancak printf %b '...' | pythondaha fazla sağlamlık için kullanmanızı öneririm , çünkü giriş dizesindeki (format belirteçleri) printfgibi dizileri yorumlamayı önler %d. Ayrıca, açıkça Python komut dizenize (bu kafa karıştırıcı olabilir) kabuk genişletmelerini uygulamak istemiyorsanız, kabuğun uyguladığı 'genişleme ve boşluk işlemesini önlemek için dış tırnak için (tek tırnak) kullanmak daha iyidir çift ​​tırnaklı dizgiler.
mklement0

5

single/double quotesve backslashher yerde:

$ python -c 'exec("import sys\nfor i in range(10): print \"bob\"")'

Çok daha iyi:

$ python -c '
> import sys
> for i in range(10):
>   print "bob"
> '

yani. çok. daha iyi.
Marc

4

(23 Kasım 10: 19'da cevaplandı) Gerçekten büyük bir Pythoner değilim - ama bu sözdizimini bir kez buldum, nereden unuttum, bu yüzden belgelediğimi düşündüm:

Eğer kullanırsanız sys.stdout.writeyerine print( fark varlık, sys.stdout.writeparantez içinde, bir fonksiyonu olarak argüman alır - oysa printdeğil ), sonra tek astar için, komut sırasını tersine çevirmekle ilgili kurtulmak ve olabilir for, noktalı virgül kaldırarak, ve komutun köşeli parantez içine alınması, yani:

python -c "import sys; [sys.stdout.write('rob\n') for r in range(10)]"

Bu sözdiziminin Python'da nasıl çağrılacağını bilmiyorum :)

Bu yardımcı olur umarım,

Şerefe!


(EDIT Sal 9 Nis 20:57:30 2013) Sanırım sonunda tek gömlekli bu köşeli parantezlerin ne hakkında olduğunu buldum; bunlar "liste kavrayışları" dır (görünüşe göre); ilk olarak Python 2.7'de not edin:

$ STR=abc
$ echo $STR | python -c "import sys,re; a=(sys.stdout.write(line) for line in sys.stdin); print a"
<generator object <genexpr> at 0xb771461c>

Böylece yuvarlak parantez / parantez içindeki komut bir "jeneratör nesnesi" olarak görülür; arayarak "yinelersek" next()- parantez içindeki komut yürütülür (çıktıdaki "abc" yi not edin):

$ echo $STR | python -c "import sys,re; a=(sys.stdout.write(line) for line in sys.stdin); a.next() ; print a"
abc
<generator object <genexpr> at 0xb777b734>

Şimdi köşeli parantezler kullanırsak - next()komutun yürütülmesi için çağırmamız gerekmediğini unutmayın, atamadan hemen sonra yürütülür; Ancak daha sonra muayene ortaya koymaktadır aedilir None:

$ echo $STR | python -c "import sys,re; a=[sys.stdout.write(line) for line in sys.stdin]; print a"
abc
[None]

Bu köşeli parantez için aramak için çok fazla bilgi bırakmıyor - ama açıkladığımı düşündüğüm bu sayfaya rastladım:

Python İpuçları Ve Püf Noktaları - Birinci Baskı - Python Öğreticiler | Dream.In.Code :

Hatırlarsanız, tek hatlı bir jeneratörün standart formatı, parantez içindeki döngü için bir tür 'for' döngüsüdür. Bu, yalnızca bir yönde yineleyebileceğiniz ve sona ulaştığınızda tekrar kullanamayacağınız bir nesne olan 'tek atış' yinelenebilir bir nesne üretecektir.

'Liste kavraması', normal köşeli parantez - () - köşeli parantez - [] ile değiştirilmesinin dışında, normal tek satırlı bir jeneratörle hemen hemen aynı görünür. Alist kavrayışının en büyük avantajı, 'tek atış' yinelenebilir bir nesne yerine bir 'liste' üreten, böylece ileri geri gidip öğeler ekleyebileceğiniz, sıralayabileceğiniz vb.

Ve aslında bir liste - sadece ilk öğesi yürütülür yürütülmez hiçbiri olmaz:

$ echo $STR | python -c "import sys,re; print [sys.stdout.write(line) for line in sys.stdin].__class__"
abc
<type 'list'>
$ echo $STR | python -c "import sys,re; print [sys.stdout.write(line) for line in sys.stdin][0]"
abc
None

Liste kavrayışları aksi 5'de belgelenmiştir . Veri Yapıları: 5.1.4. Liste Anlamaları - Python v2.7.4 “Liste anlaşmaları liste oluşturmak için kısa ve öz bir yol sağlar”; muhtemelen, listelerin sınırlı "çalıştırılabilirliği" tek satırda devreye giriyor.

Umarım buradaki işaretten çok da kötü değilim ...

EDIT2: ve burada iç içe yerleştirilmemiş iki döngüye sahip tek satırlı bir komut satırı; her ikisi de "liste kavrama" köşeli parantez içine alınmış:

$ echo $STR | python -c "import sys,re; a=[sys.stdout.write(line) for line in sys.stdin]; b=[sys.stdout.write(str(x)) for x in range(2)] ; print a ; print b"
abc
01[None]
[None, None]

İkinci "liste" nin bşimdi iki unsuru olduğuna dikkat edin , çünkü for döngüsü açık olarak iki kez koştu; ancak, sys.stdout.write()her iki durumda da (görünüşe göre) sonucuydu None.


4

Bu varyant, Windows ve * nix, py2 / 3'teki komut satırına çok satırlı komut dosyaları eklemeksizin en portatiftir:

python -c "exec(\"import sys \nfor r in range(10): print('rob') \")"

(Şimdiye kadar burada görülen diğer örneklerin hiçbiri bunu yapmadı)

Windows'da düzgün:

python -c exec"""import sys \nfor r in range(10): print 'rob' """
python -c exec("""import sys \nfor r in range(10): print('rob') """)

Bash / * nix'te düzgün:

python -c $'import sys \nfor r in range(10): print("rob")'

Bu işlev, herhangi bir çok satırlı komut dosyasını taşınabilir bir komut satırı klasörüne dönüştürür:

def py2cmdline(script):
    exs = 'exec(%r)' % re.sub('\r\n|\r', '\n', script.rstrip())
    print('python -c "%s"' % exs.replace('"', r'\"'))

Kullanımı:

>>> py2cmdline(getcliptext())
python -c "exec('print \'AA\tA\'\ntry:\n for i in 1, 2, 3:\n  print i / 0\nexcept:\n print \"\"\"longer\nmessage\"\"\"')"

Girdi:

print 'AA   A'
try:
 for i in 1, 2, 3:
  print i / 0
except:
 print """longer
message"""

Çapraz platform açısı ve dönüştürücü için ++. İlk komutunuz taşınabilirlik açısından aldığı kadar iyidir (PowerShell'i bir kenara bırakarak), ancak sonuçta tek, tamamen sağlam bir platformlar arası sözdizimi yoktur, çünkü çift tırnak kullanma ihtiyacı daha sonra istenmeyen kabuk genişleme riskini taşır. POSIX benzeri kabuklardan farklı karakterlerden kaçmayı gerektiren Windows. PowerShell v3 veya sonraki sürümlerinde --%, komut dizesi bağımsız değişkeninden önce "dur ayrıştırma" seçeneğini ekleyerek komut satırlarınızın çalışmasını sağlayabilirsiniz .
mklement0

@ mklement0 " istenmeyen kabuk açılımları ": Şey , kabuk açılımlarının print "path is %%PATH%%"resp gibi bir şeye eklenmesi . print "path is $PATH"genellikle bir komut dosyasında veya komut satırında istediği seçenektir - platform için olağan şeylerden kaçmadıkça. Diğer dillerle aynı. (Python sözdiziminin kendisi düzenli olarak% ve $ 'ların rakip bir şekilde kullanılmasını
önermez

Kabuk değişkeni referanslarını doğrudan Python kaynak koduna eklerseniz tanım olarak taşınabilir olmaz. Benim demek olduğunu, bunun yerine de platforma özel referanslar inşa bile ayrı sizin geçmek değişkenler argümanlar olarak bir karşı single'ı "kabuk içermeyen" olduğunu, Python komutu may Eğer çift tırnaklı dize koruyamaz, çünkü iş her zaman değil portably : örneğin, Python kodunuzda değişmez ifadeye ihtiyacınız varsa ne olacak $foo? Eğer gibi kaçış Eğer \$fooyararına POSIX'e benzeri kabuklar, cmd.exehala ekstra göreceksiniz \ . Nadir olabilir ama bilmeye değer.
mklement0

Bunu Windows PowerShell'de yapmaya çalışıyorum, ancak sorun, python -c exec ("" "..." ""), kodun yürütülebilmesine bakılmaksızın herhangi bir çıktı üretmemesidir. ya da değil; Orada herhangi bir anlamsızlık koyabilirdim ve sonuç aynı olurdu. Kabuğun hem stdout hem de stderr akışlarını "yediği" gibi hissediyorum - onları tükürmesini nasıl sağlayabilirim?
Yury


1

Bunu yapmam gerektiğinde

python -c "$(echo -e "import sys\nsys.stdout.write('Hello World!\\\n')")"

Sys.stdout.write deyiminde yeni satır için üçlü ters eğik çizgiye dikkat edin.


Bu çalışıyor, ancak echo -estandart olmayan ve gerektiren bash, kullandığınız için ksh, ya da doğrudan zshbir $'...'dize de kullanabilirsiniz , bu da kaçmayı basitleştirir:python -c $'import sys\nsys.stdout.write("Hello World!\\n")'
mklement0

Bu cevap çalışıyor, diğer cevaplar Python3 için çalışmıyor

1

Aşağıdaki özelliklere sahip bir çözüm istedim:

  1. Okunabilir
  2. Diğer araçların çıktılarını işlemek için stdin'i okuyun

Diğer yanıtlarda her iki gereksinim de sağlanmadı, bu nedenle komut satırında her şeyi yaparken stdin'i nasıl okuyacağınız aşağıda açıklanmıştır:

grep special_string -r | sort | python3 <(cat <<EOF
import sys
for line in sys.stdin:
    tokens = line.split()
    if len(tokens) == 4:
        print("%-45s %7.3f    %s    %s" % (tokens[0], float(tokens[1]), tokens[2], tokens[3]))
EOF
)

0

bir seçenek daha var, sys.stdout.write, listeyi boş tutan None değerini döndürür

cat somefile.log | python -c "içe aktarma sys; [sys.stdout.write ise sys.stdin'deki satır için satır (satır * 2)]"


0

Stdin'e dokunmak ve "python cmdfile.py" dosyasını geçmiş gibi simüle etmek istemiyorsanız, bir bash kabuğundan aşağıdakileri yapabilirsiniz:

$ python  <(printf "word=raw_input('Enter word: ')\nimport sys\nfor i in range(5):\n    print(word)")

Gördüğünüz gibi, giriş verilerini okumak için stdin'i kullanmanıza izin verir. Dahili olarak kabuk, giriş komutu içerikleri için geçici dosya oluşturur.


++ stdin'i komut dosyasının kendisiyle "kullanmamak" için ( -c "$(...)"aynı şeyi yapar ve POSIX uyumludur); <(...)yapıya bir isim vermek için : işlem ikamesi ; o da çalışır kshve zsh.
mklement0
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.