Domanda Esiste un equivalente Python a `perl -pi -e`?


So di python -c '<code>', ma mi chiedo se ci sia un equivalente python più elegante di perl -pi -e '<code>'. Lo uso ancora un po 'per cose come find e replace in una directory intera (perl -pi -e s/foo/bar/g * o anche find . | xargs perl -pi -e s/foo/bar/g per sottodirectory).

In realtà sento che ciò che rende Perl Perl (forma libera Tim Toady-ness) è ciò che rende perl -pi -e funziona così bene, mentre con Python dovresti fare qualcosa sulla falsariga di importare il modulo re, creare una re instance e quindi catturare lo stdin, ma forse c'è un collegamento Python che fa tutto questo e l'ho perso (mi è mancato molto ) ...


16
2017-12-14 22:57


origine


risposte:


L'utilizzo della riga di comando da 'python -h'certamente suggerisce fortemente che non esiste un simile equivalente. Perl tende a fare ampio uso di '$_'(i tuoi esempi ne fanno un uso implicito), e non penso che Python supporti alcun concetto simile, rendendo quindi molto più difficili gli equivalenti di Python degli one-liner Perl.


10
2017-12-14 23:53



Python è per i babbani. Se vuoi magia, Perl dovresti usare!


26
2017-12-15 00:58



Un equivalente a -pi non è così difficile da scrivere in Python.

  1. Scrivi te stesso un pratico modulo con le funzionalità -p e -i che ti piacciono davvero. Chiamiamolo pypi.py.

  2. Uso python -c 'import pypi; pypi.subs("this","that")'

È possibile implementare il ciclo di base -p con il fileinput modulo.

Avresti una funzione, subs che implementa l'algoritmo "-i" essenziale per aprire un file, salvare la copia di backup e fare il sostituto su ogni riga.

Ci sono alcune ricette attive come questa. Eccotene alcune:

Non integrato. Ma non è difficile da scrivere. E una volta scritto facile da personalizzare.


10
2018-01-20 21:45



So che questo è un paio di anni troppo tardi, ma di recente trovato un bellissimo strumento chiamato PYP, che fa esattamente quello che hai chiesto.

Penso che il tuo comando dovrebbe essere:

pyp "p.replace('foo','bar')"

9
2017-12-15 01:23



Penso che perl sia più adatto per questo tipo di script on-the-fly. Se si desidera una rapida funzionalità di scripting one-off, si consiglia di attenersi agli strumenti da riga di comando perl, awk, sed e standard della riga di comando unix.

Ma se sei interessato a usare Python, io lo uso optparse scrivere i miei strumenti da riga di comando e raccomandarlo. optparse fornisce un parser di opzioni da riga di comando pulito e facile da usare con la generazione di aiuto integrata.

Ecco un esempio:

def myfunc(filename, use_versbose):
   # function code

if __name__ == '__main__':
    from optparse import OptionParser

    parser = OptionParser()
    parser.add_option("-f", "--file", dest="filename",
                      help="write report to FILE", metavar="FILE")
    parser.add_option("-q", "--quiet",
                      action="store_false", dest="verbose", default=True,
                      help="don't print status messages to stdout")

    (options, args) = parser.parse_args()

    if options.filename:
        myfunc(options.filename, options.verbose)

    else:
        print 'ERROR -- Necessary command line options not given!'
        print parser.print_help()

parser.print_help () genera il seguente output e viene visualizzato automaticamente quando -h o --help viene dato alla riga di comando:

usage: <yourscript> [options]

options:
  -h, --help            show this help message and exit
  -f FILE, --file=FILE  write report to FILE
  -q, --quiet           don't print status messages to stdout

6
2018-03-08 01:05



Il modulo fileinput ha la capacità di modificare sul posto. Non è possibile fare a meno dei backup, però. Ecco come usarlo per un one-liner:

python -c 'import fileinput, sys; for line in fileinput.input(inplace=True): sys.stdout.write(line, "foo", "bar")'

Personalmente, di solito uso il Perl quando devo fare qualcosa del genere. È una delle poche volte che uso Perl.


2
2017-07-15 13:00



Quanto sopra può funzionare per stdin, ma non sembra che funzioni per un file.

Forse qualcosa come:

-

import fileinput 
import sys
for line in fileinput.input("./poop", inplace=True):
    line = line.replace("foo", "bar")
    sys.stdout.write(line)

- dove "./poop" può essere sostituito con il punto in cui si trova il file e line.replace dovrebbe supportare cose come line.replace ("{}". format (variablehere), "newtext")


0