Извлечь похожие строки из нескольких файлов в папке - PullRequest
0 голосов
/ 28 января 2019

У меня есть каталог с примерно 30 файлами Python с похожим шаблоном, примерно так:

import stuff

class BarFoo001(BarFooBase):

    info = self.info
    description = 'here's the stuff I want'
    IS_CRITICAL = true

    def method(sdf):
        etc...

Я бы хотел извлечь из каждого файла только строки с именем класса и описанием (просто текстдля справки мне не нужен рабочий файл Python).

Моей первой мыслью было сделать это с помощью инструментов оболочки.Я использовал cat *.py > all.py, а затем попытался sed -i -e 's/BarFooBase\(.*\)IS_CRITICAL/\1/' all.py, но это, похоже, не дало результата.Я также пытался использовать RegEx в своей IDE и, наконец, в Python (re.sub('IS_CRITICAL[^>]+\nclass Bar', '', my_string)), но ни один из них не дал мне желаемых результатов.Что не так с моим Regex?Кроме того, есть ли более простой способ сделать это, что я упускаю?

Вот будет достаточно хороший вывод:

класс BarFoo001 (BarFooBase):

info = self.info
description = 'вот что я хочу'
IS_CRITICAL

Ответы [ 5 ]

0 голосов
/ 28 января 2019
$ grep -E '^[[:space:]]*(class|description)[[:space:]]' file
class BarFoo001(BarFooBase):
    description = 'here's the stuff I want'

$ awk 'sub(/^[[:space:]]*(class|description =)[[:space:]]+/,"")' file
BarFoo001(BarFooBase):
'here's the stuff I want'
0 голосов
/ 28 января 2019

Использование Perl one-liner

 perl -0777 -ne ' while( /(\bclass\s*.+?IS_CRITICAL)/gs ) { print "$1\n" } ' 

со входами:

$ cat josh.py
import stuff

class BarFoo001(BarFooBase):

    info = self.info
    description = 'here's the stuff I want'
    IS_CRITICAL = true

    def method(sdf):
        etc...
    def method2(fddf):
        print
$ perl -0777 -ne ' while( /(\bclass\s*.+?IS_CRITICAL)/gs ) { print "$1\n" } ' josh.py
class BarFoo001(BarFooBase):

    info = self.info
    description = 'here's the stuff I want'
    IS_CRITICAL
$

Для поиска нескольких файлов вы можете использовать

perl -0777 -ne ' while( /(\bclass\s*.+?IS_CRITICAL)/gs ) { print "$ARGV:$1\n" } ' *py
0 голосов
/ 28 января 2019

С помощью sed вы можете использовать диапазон адресов для вывода блоков строки:

sed -n '/^[[:blank:]]*class[[:blank:]]/,/IS_CRITICAL/p' file.py

Редактировать:

Добавлено [[:blank:]] до и после classсоответствовать только определениям классов, которым предшествует ноль или более пробелов или табуляций.

0 голосов
/ 28 января 2019

Не могли бы вы попробовать следующее.Он должен работать во всех видах awk версий, но не может тестироваться во всех версиях или разных системах ОС.

awk '
{
  sub(/^ +/,"")
}
/class/{
  found=1
}
/IS_CRITICAL/ && found{
  sub(/ =.*/,"")
  print
  found=""
}
found
'  Input_file
0 голосов
/ 28 января 2019

Попробуйте, посмотрите, соответствуют ли вам результаты (GNU awk):

awk '/IS_CRITICAL/{sub(/IS_CRITICAL.*/,"IS_CRITICAL");print "class " $0}' RS="class " all.py
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...