Python эквивалентен perl -pe?

Мне нужно выбрать некоторые номера из некоторых текстовых файлов. Я могу выбрать строки, которые мне нужны, с grep, но не знал, как извлекать числа из строк. Коллега показал мне, как это сделать из bash с perl:

cat results.txt | perl -pe 's/.+(\d\.\d+)\.\n/\1 /'

Однако, я обычно код в Python, а не Perl. Итак, мой вопрос: мог ли я использовать Python таким же образом? Я мог бы передать что-то от bash до Python, а затем получить результат прямо к stdout?... если это имеет смысл. Или Perl просто удобнее в этом случае?

Ответ 1

Да, вы можете использовать Python из командной строки. python -c <stuff> будет запускать <stuff> как код Python. Пример:

python -c "import sys; print sys.path"

Не существует прямого эквивалента опции -p для Perl (автоматическая обработка ввода/вывода по очереди), но в основном потому, что Python не использует ту же концепцию $_ и whatnot что Perl делает - в Python все вход и выход выполняется вручную (через raw_input()/input() и print/print()).


В вашем конкретном примере:

cat results.txt | python -c "import re, sys; print ''.join(re.sub(r'.+(\d\.\d+)\.\n', r'\1 ', line) for line in sys.stdin)"

(Очевидно, несколько более громоздко. Вероятно, лучше просто написать script для этого в реальном Python.)

Ответ 2

Вы можете использовать:

$ python -c '<your code here>'

Ответ 3

Вы можете теоретически, но Python не имеет ни малейшей магии регулярных выражений, что делает Perl, поэтому полученная команда будет намного более громоздкой, особенно если вы не можете использовать регулярные выражения без импорта re (и вам, вероятно, понадобится sys для sys.stdin).

эквивалент Python вашего коллеги Perl с одним слоем:

import sys, re
for line in sys.stdin:
    print re.sub(r'.+(\d\.\d+)\.\n', r'\1 ', line)

Ответ 4

У вас есть проблема, которая может быть решена несколькими способами.

Я думаю, вам следует использовать регулярное выражение (что делает perl в вашем примере) прямо из Python. Регулярные выражения находятся в модуле re. Примером может служить:

import re
filecontent = open('somefile.txt').read()
print re.findall('.+(\d\.\d+)\.$', filecontent)

(я бы предпочел использовать $ вместо '\n' для окончаний строк, потому что окончания строк различаются между операционными системами и кодировками файлов)

Если вы хотите вызывать команды bash изнутри Python, вы можете использовать:

import os
os.system(mycommand)

Где команда - команда bash. Я использую его все время, потому что некоторые операции лучше выполнять в bash, чем в Python.

Наконец, если вы хотите извлечь числа с помощью grep, используйте параметр -o, который печатает только согласованную часть.

Ответ 5

Вы можете использовать python для выполнения кода непосредственно из командной строки bash, используя python -c, или вы можете обрабатывать входные каналы на stdin с помощью sys.stdin, см. здесь.

Ответ 6

Perl (или sed) более удобен. Однако это возможно, если уродливо:

python -c 'import sys, re; print "\n".join(re.sub(".+(\d\.\d+)\.\n","\1 ", l) for l in sys.stdin)'