Python'da yaygın bash deyimleri nasıl uygulanır? [kapalı]


242

Şu anda textfile manipülasyonumu kötü hatırlanmış bir grup AWK, sed, Bash ve biraz da Perl ile yapıyorum.

Python'un bu tür şeyler için iyi olduğu birkaç yerden bahsetmiştim. Kabuk komut dosyası oluşturma, AWK, sed ve arkadaşları değiştirmek için Python'u nasıl kullanabilirim?


3
pythonpy python sözdizimini kullanarak awk ve sed için iyi bir rakip: github.com/Russell91/pythonpy
RussellStewart


Benim sorum bu, neden fikre dayandığını anlamıyorum. Üst yanıt, bir kabuğun yaptığı her şeyi listeler ve bunları python'da nasıl yapacağınızı anlatır. Bence bu soruyu görüşsüz bir şekilde cevaplıyor.
Chris Jefferson

Bu soru ve kapanışı, burada
Erik A

Yanıtlar:


144

Herhangi bir kabuğun çeşitli özellikleri vardır.

  • Essential Linux / Unix komutları. Bunların tümüne alt işlem kütüphanesi aracılığıyla erişilebilir . Bu, tüm harici komutları yapmak için her zaman en iyi ilk seçenek değildir . Ayrı Linux komutları olan bazı komutları da kapatabilirsiniz , ancak muhtemelen doğrudan Python komut dosyalarınıza uygulayabilirsiniz. Bir başka büyük Linux komutları os kütüphanesinde; bunları daha basit bir şekilde Python'da yapabilirsiniz.

    Ve - bonus! -- daha hızlı bir şekilde. Kabuktaki her bir ayrı Linux komutu (birkaç istisna dışında) bir alt süreci çatallar. Python shutilve osmodülleri kullanarak bir alt süreci çatallamazsınız.

  • Kabuk ortamının özellikleri. Bu, bir komutun ortamını ayarlayan öğeleri içerir (geçerli dizin ve ortam değişkenleri ve neyin değil). Bunu doğrudan Python'dan kolayca yönetebilirsiniz.

  • Kabuk programlama özellikleri. Bu, tüm işlem durum kodu denetimi, çeşitli mantık komutları (eğer, while, için, vb.) Ve tüm akrabalarıdır. Fonksiyon tanımlaması. Python'da bu çok, çok daha kolay. Bu, bash'tan kurtulmanın ve Python'da yapmanın büyük zaferlerinden biridir.

  • Etkileşim özellikleri. Buna komut geçmişi ve neyin dahil olmadığı da dahildir. Kabuk komut dosyaları yazmak için buna ihtiyacınız yoktur. Bu sadece insan etkileşimi içindir, senaryo yazmak için değildir.

  • Kabuk dosya yönetimi özellikleri. Buna yönlendirme ve boru hatları da dahildir. Bu daha hileli. Bunların çoğu alt işlemle yapılabilir. Ancak kabuğunda kolay olan bazı şeyler Python'da hoş değildir. Özellikle gibi şeyler (a | b; c ) | something >result. Bu, paralel olarak iki işlem yürütür (çıktı aolarak girdi olarak b), ardından üçüncü bir işlem izler. Bu diziden gelen çıktı paralel olarak çalıştırılır somethingve çıktı adlı bir dosyaya toplanır result. Başka bir dilde ifade etmek sadece karmaşık.

Belirli programlar (awk, sed, grep, vb.) Genellikle Python modülleri olarak yeniden yazılabilir. Aşırıya kaçmayın. İhtiyacınız olanı değiştirin ve "grep" modülünüzü geliştirin. "Grep" yerine geçen bir Python modülü yazmaya başlamayın.

En iyi şey, bunu adım adım yapabilmenizdir.

  1. AWK ve PERL'yi Python ile değiştirin. Diğer her şeyi rahat bırakın.
  2. GREP'yi Python ile değiştirmeye bakın. Bu biraz daha karmaşık olabilir, ancak GREP sürümünüz işleme gereksinimlerinize göre uyarlanabilir.
  3. FIND yerine kullanılan Python döngülerini değiştirmeye bakın os.walk. Bu çok büyük bir kazanç çünkü çok fazla süreç yaratmıyorsunuz.
  4. Genel kabuk mantığını (döngüler, kararlar, vb.) Python komut dosyalarıyla değiştirmeye bakın.

6
wrote: "Etkileşim özellikleri. Bu komut geçmişi içerir ve ne-değil. Buna ihtiyacınız yok." Kimsenin bir kişinin gerçekten neye ihtiyacı olup olmadığını söyleyemediğinden korkuyorum. Belki de yapar. Ayrıca, bu tesisler, Idle ve IPython arasındaki farkı örnek alarak, etkileşimli bir kabukta çok mantıklıdır.
Mart'ta heltonbiker

47
Ben içtenlikle insanların tamamen kabuk komut dosyası hendek istiyorum. Bilgisayar korsanlığının pratikte * nix dünyasında bir din olduğunu anlıyorum, ancak işletim sistemine yerleştirilen tüm hackish çözümlerini yorumlamaktan gerçekten yoruldum. Mikroaletlerin yeniliği (awk, sed, top, base, vb.) Herkesin kendi versiyonunu kullanmaya karar verdiği gün yıprandı. Bir çift iyi tasarlanmış Python modülü ile kolayca değiştirilebilecek boktan küçük aletlerde harcanan adam-saat miktarını hayal ettiğimde küfrediyorum. :: iç çekme ::
Evan Plaice

40
@EvanPlaice'e katılmıyorum, çünkü findsahip olduğum birkaç komut dosyasının python sürümü çirkin ve uzun ve karşılaştırılamaz. Birçok şey kabuk komut dosyaları olmalı , birçok şey olmamalıdır . Her şeyin sadece bir Python veya BASH (veya başka bir şey) olması gerekmez.
mikebabcock

8
mikebabcock İdeal olarak, temel * nix yığını tarafından sunulan tüm mikro araçları uygulayan eksiksiz bir kütüphane olacaktır. Find () ve last () gibi işlevler dahil edilir ve borular yerine, bir körük ve tembel yükleme kombinasyonu, bunların birbirine yapışmasını sağlar. Tüm dağıtımlarda standart bir şekilde çalışan bir POSIX komut dosyası oluşturma ortamına sahip olmak hoş olmaz mıydı? Böyle bir şey henüz yok, ...
Evan Plaice

2
Kabuk boru hatları (örneğin (a | b; c ) | something >result) ile ilgili nokta , kabuk boru hatlarını şu subprocessyöntemlere shell=True
geçirmenin

103

Evet tabi ki :)

Bir daha asla kabuk komut dosyaları yazmanıza yardımcı olan bu kütüphanelere bir göz atın (Plumbum'un sloganı).

Ayrıca, awk, sed ve grep'i Python tabanlı bir şeyle değiştirmek istiyorsanız pyp'i öneriyorum -

"Pyed Piper" veya pyp, awk veya sed'e benzeyen bir linux komut satırı metin manipülasyon aracıdır, ancak yoğun bir üretim ortamında hızlı sonuçlar üretmek için geliştirilmiş standart fonksiyonların yanı sıra standart python dizesi ve liste yöntemlerini kullanır.



57

Bash ve ipython'un en iyi kısımlarını nasıl birleştireceğimizi keşfettim. Şimdiye kadar bu benim için alt süreci kullanmaktan daha rahat görünüyor. Mevcut bash komut dosyalarının büyük bölümlerini kolayca kopyalayabilir ve örneğin python yolunda hata işleme ekleyebilirsiniz :) Ve işte sonuç:

#!/usr/bin/env ipython3

# *** How to have the most comfort scripting experience of your life ***
# ######################################################################
#
# … by using ipython for scripting combined with subcommands from bash!
#
# 1. echo "#!/usr/bin/env ipython3" > scriptname.ipy    # creates new ipy-file
#
# 2. chmod +x scriptname.ipy                            # make in executable
#
# 3. starting with line 2, write normal python or do some of
#    the ! magic of ipython, so that you can use unix commands
#    within python and even assign their output to a variable via
#    var = !cmd1 | cmd2 | cmd3                          # enjoy ;)
#
# 4. run via ./scriptname.ipy - if it fails with recognizing % and !
#    but parses raw python fine, please check again for the .ipy suffix

# ugly example, please go and find more in the wild
files = !ls *.* | grep "y"
for file in files:
  !echo $file | grep "p"
# sorry for this nonsense example ;)

Bkz. Sistem kabuğu komutlarındaki IPython belgeleri ve sistem kabuğu olarak kullanma .


11
Bazı tuhaf nedenlerden dolayı, hiç kimse bahsetmedi! -IPython'da kesinlikle anahtar olan komutlar; özellikle de çıktılarını olduğu gibi bir değişkene (satır listesi) atayabileceğiniz içinfilelines = ! cat myfile
kampu

Ve $varbir kabuk komutunda olduğu gibi python değişkenlerini kullanabilirsiniz ? Vay. Bu kabul edilen cevap olmalı.
Chiel ten Brinke

Ve bunu jupyter defterlerinden de kullanabilirsiniz
Yuval Atzmon

44

2015 ve Python 3.4'ün piyasaya sürülmesinden itibaren, şu anda makul derecede eksiksiz bir kullanıcı etkileşimli kabuk bulunmaktadır: http://xon.sh/ veya https://github.com/scopatz/xonsh

Tanıtım videosunu borular kullanılıyor, ancak varsayılan kabuk modunda onlar desteklenen ARE göstermez.

Xonsh ('conch') bash'ı taklit etmek için çok çalışıyor, bu yüzden zaten kas belleği kazandığınız şeyler,

env | uniq | sort -r | grep PATH

veya

my-web-server 2>&1 | my-log-sorter

hala iyi çalışır.

Öğretici oldukça uzundur ve birisinin genellikle bir kül veya bash isteminde bekleyeceği işlevselliğin önemli bir bölümünü kapsamaktadır:

  • Derler, Değerlendirir ve Yürütür!
  • Komut Geçmişi ve Sekme Tamamlama
  • Yardım ve Süper Yardım ?&??
  • Takma Adlar ve Özelleştirilmiş Uyarılar
  • *.xshİçe aktarılabilen Komutları ve / veya Komut Dosyalarını yürütür
  • İle Arama Dahil Ortam Değişkenleri ${}
  • Giriş / Çıkış Yönlendirme ve Birleştirme
  • Arkaplan İşleri ve İş Kontrolü
  • Alt İşlemleri, Boruları ve Yardımcı İşlemleri Yerleştirme
  • Bir komut olduğunda alt işlem modu, aksi takdirde Python modu
  • İle Yakalanan Alt Süreç $(), İle Yakalanmamış Alt Süreç, İle $[]Python Değerlendirmesi@()
  • Dosya adı globbing *veya düzenli ifade Dosya adı globbing backticks ile

Ama neden tüm bu cevaplar bash bilmeyen insanlar için tekerleği yeniden icat ediyor gibi görünüyor ? Ben bash ile orta derecede rahat aldım ve bu cevapların her biri az fayda için daha fazla iş olacak gibi görünüyor. Bu cevapların hepsi bash'den korkan (veya öğrenmek için zaman harcamak istemeyen) piton insanlarına yöneliktir, değil mi?
Buttle Butkus

.xshXonsh kodu olan dosyalar için uzantı kullanma gereksinimi gibi bazı dezavantajları var gibi görünüyor : github.com/xonsh/xonsh/issues/2478 . Aksi takdirde evalxdoğrudan .pydosyalardan aramak için kullanmanız gerekir .
Andry

31
  • Python'u kabuk olarak kullanmak istiyorsanız, neden IPython'a bir göz atmıyorsunuz ? Dili etkileşimli olarak öğrenmek de iyidir.
  • Çok fazla metin manipülasyonu yaparsanız ve Vim'i metin editörü olarak kullanırsanız, doğrudan Pimhon'da Vim için eklentiler yazabilirsiniz. Vim'de ": help python" yazıp talimatları izleyin veya bu sunuma bir göz atın . Doğrudan editörünüzde kullanacağınız fonksiyonları yazmak o kadar kolay ve güçlü ki!

8
tercüman yapar 'sh' adlı bir ipython profili var çok bir kabuk gibi çok.
Autoplectic

3
İpython 'sh' profili bir süredir kaldırıldı.
gdw2

>>> sonuç =! dmesg | grep -i 'usb' #the! operatör her şeyi yapıyor
Permafacture

16

Başlangıçta sh, sed ve awk vardı (ve bul, grep ve ...). İyiydi. Ama awk garip bir küçük canavar olabilir ve sık kullanmazsanız hatırlanması zor olabilir. Sonra büyük deve Perl'i yarattı. Perl bir sistem yöneticisinin hayaliydi. Steroidler üzerinde kabuk betikleri gibiydi. Düzenli ifadeler dahil olmak üzere metin işleme, dilin sadece bir parçasıydı. Sonra çirkinleşti ... İnsanlar Perl ile büyük uygulamalar yapmaya çalıştı. Şimdi, beni yanlış anlamayın, Perl bir uygulama olabilir, ama gerçekten dikkatli değilseniz bir karmaşa gibi görünebilir. Sonra tüm bu düz veri işi var. Bir programcı somunu sürmek yeterlidir.

Python, Ruby ve ark. Bunlar gerçekten çok iyi genel amaçlı diller. Metin işlemeyi desteklerler ve bunu iyi yaparlar (belki de dilin temel çekirdeğine sıkıca bağlı olmasalar da). Ama aynı zamanda çok iyi ölçekleniyorlar ve günün sonunda hala güzel görünümlü kodları var. Ayrıca, her şey için bol miktarda kütüphaneye sahip oldukça büyük topluluklar geliştirdiler.

Şimdi, Perl'e karşı olumsuzluğun çoğu bir görüş meselesidir ve kesinlikle bazı insanlar çok temiz Perl yazabilirler, ancak bu birçok insan gizli kod oluşturmanın çok kolay olduğundan şikayet ediyor, bazı gerçek tahıllar olduğunu biliyorsunuz. O zaman soru gerçekten olur, bu dili basit bash betiği değiştirmelerinden daha fazlası için kullanacak mısınız? Değilse, biraz daha bilgi Perl .. bunun için kesinlikle harika. Öte yandan, daha fazlasını yapmak istediğiniz gibi sizinle birlikte büyüyecek bir dil istiyorsanız, Python veya Ruby önerebilir miyim.

Her iki şekilde de, iyi şanslar!




7

Python'u sevmemin bir nedeni, POSIX araçlarından çok daha iyi standartlaştırılmış olmasıdır. Her bir bitin diğer işletim sistemleriyle uyumlu olup olmadığını iki ve üç kez kontrol etmeliyim. Linux sisteminde yazılmış bir program, OSX'in BSD sisteminde aynı şekilde çalışmayabilir. Python ile, hedef sistemin Python'un yeterince modern bir versiyonuna sahip olup olmadığını kontrol etmeliyim.

Daha da iyisi, standart Python'da yazılmış bir program Windows'ta bile çalışacaktır!


1
"Standart Python'da yazılmış bir program Windows üzerinde bile çalışır": şaka yapmıyor musunuz?
Jean-François Fabre

6

Burada deneyime dayanarak fikrimi vereceğim:

Kabuk için:

  • kabuk, salt okunur kodu kolayca oluşturabilir. Yazın ve ona geri döndüğünüzde, bir daha ne yaptığınızı asla anlamayacaksınız. Bunu başarmak çok kolay.
  • kabuk borular ile bir satırda bir çok metin işleme, bölme, vb yapabilirsiniz.
  • farklı programlama dillerindeki programların çağrısını entegre etmek söz konusu olduğunda en iyi tutkal dilidir.

Python için:

  • pencerelere taşınabilirlik dahil etmek istiyorsanız, python kullanın.
  • sayı toplama gibi metinden daha fazlasını işlemeniz gerektiğinde python daha iyi olabilir. Bunun için python öneririm.

Çoğu şey için genellikle bash'ı seçerim, ancak windows sınırlarını aşması gereken bir şey olduğunda, sadece python kullanıyorum.


4

pythonpy , awk ve sed özelliklerinin çoğuna kolay erişim sağlayan, ancak python sözdizimini kullanan bir araçtır:

$ echo me2 | py -x 're.sub("me", "you", x)'
you2

3

Benzer işlevsellik yapan yarı uzun kabuk komut dosyaları (300-500 satır) ve Python kodu oluşturdum. Birçok harici komut yürütüldüğünde kabuğun kullanımını daha kolay buluyorum. Perl ayrıca çok fazla metin manipülasyonu olduğunda iyi bir seçenektir.



2

En iyi bahsiniz, özellikle sorununuza yönelik bir araçtır. Metin dosyalarını işliyorsa, Sed, Awk ve Perl en iyi yarışmacılardır. Python genel amaçlı dinamik bir dildir. Herhangi bir genel amaçlı dilde olduğu gibi, dosya manipülasyonu için destek vardır, ancak asıl amacı bu değildir. Özellikle dinamik bir dile gereksinimim olsaydı Python veya Ruby'yi düşünürdüm.

Kısacası, Sed ve Awk'i gerçekten iyi öğrenin, ayrıca * nix (Tüm Bash yerleşikleri, grep, tr ve benzeri) lezzetinizle gelen diğer tüm güzellikleri öğrenin. İlgilendiğiniz metin dosyası işlemesi zaten doğru olanı kullanıyorsunuz demektir.


2

ShellPy kütüphanesi ile bash yerine python kullanabilirsiniz .

İşte Pithhon kullanıcısının avatarını Github'dan indiren bir örnek:

import json
import os
import tempfile

# get the api answer with curl
answer = `curl https://api.github.com/users/python
# syntactic sugar for checking returncode of executed process for zero
if answer:
    answer_json = json.loads(answer.stdout)
    avatar_url = answer_json['avatar_url']

    destination = os.path.join(tempfile.gettempdir(), 'python.png')

    # execute curl once again, this time to get the image
    result = `curl {avatar_url} > {destination}
    if result:
        # if there were no problems show the file
        p`ls -l {destination}
    else:
        print('Failed to download avatar')

    print('Avatar downloaded')
else:
    print('Failed to access github api')

Gördüğünüz gibi, mezar aksanı (`) sembolünün içindeki tüm ifadeler kabukta yürütülür. Ve Python kodunda, bu yürütmenin sonuçlarını yakalayabilir ve üzerinde eylemler gerçekleştirebilirsiniz. Örneğin:

log = `git log --pretty=oneline --grep='Create'

Bu satır önce kabukta yürütülür git log --pretty=oneline --grep='Create've sonucu log değişkenine atar. Sonuç aşağıdaki özelliklere sahiptir:

stdout yürütülen metnin stdout'undan tüm metni

stderr çalıştırılan işlemin stderr'sinden tüm metni

dönüş kodu yürütmenin dönüş kodu

Bu kütüphaneye genel bir bakıştır, örneklerle daha ayrıntılı bir açıklama burada bulunabilir .


1

Metin dosyası manipülasyonunuz genellikle bir kerelikse, muhtemelen kabuk isteminde yapılırsa, python'dan daha iyi bir şey elde edemezsiniz.

Öte yandan, genellikle aynı (veya benzer) görevi tekrar tekrar yapmak zorundaysanız ve bunu yapmak için komut dosyalarınızı yazmanız gerekiyorsa, python harikadır - ve kendi kitaplıklarınızı kolayca oluşturabilirsiniz ( kabuk komut dosyalarıyla da, ama daha hantal).

Hissetmek için çok basit bir örnek.

import popen2
stdout_text, stdin_text=popen2.popen2("your-shell-command-here")
for line in stdout_text:
  if line.startswith("#"):
    pass
  else
    jobID=int(line.split(",")[0].split()[1].lstrip("<").rstrip(">"))
    # do something with jobID

Ayrıca sys ve getopt modülünü de kontrol edin, ihtiyacınız olan ilk bunlar.


1

PyPI: ez hakkında bir paket yayınladım . Yüklemek için
kullanın pip install ez.

Kabukta ortak komutları paketledi ve güzel benim lib temelde kabuk ile aynı sözdizimini kullanır. örneğin, cp (kaynak, hedef) hem dosya hem de klasörü işleyebilir! (shutil.copy wrail.copytree paketleyicisidir ve hangisinin ne zaman kullanılacağına karar verir). Daha da güzel, R gibi vektörleşmeyi destekleyebilir!

Başka bir örnek: os.walk yok, dosyaları özyinelemeli olarak bulmak ve düzenli ifadeyle filtrelemek için fls (yol, regex) kullanın ve tam yollu veya tam yol olmayan dosyaların bir listesini döndürür

Son örnek: çok basit komut dosyaları yazmak için bunları birleştirebilirsiniz:
files = fls('.','py$'); cp(files, myDir)

Kesinlikle kontrol edin! Yazmak / geliştirmek bana yüzlerce saat mal oldu!


1
İlginç görünüyor, ama pypi.python.org/pypi/ez adresindeki biçimlendirilmemiş dokümanları kıramam , üzgünüm ...
Greg Dubicki
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.