питон раскомментировать правую строку - PullRequest
1 голос
/ 21 октября 2010

У меня есть файл следующим образом:

line 1: _____
   ...
# for AAA
#export CONFIG = AAA_defconfig

# for BBB, BbB, Bbb, BBb3
#export CONFIG = BBB_defconfig

# for CCC, CcC, Ccc, Ccc1
#export CONFIG = CCC_defconfig
   ...
other lines

Я хочу манипулировать файлом, чтобы на основе заданной строки я мог экспортировать правильный «CONFIG» и прокомментировать остальные.например, если я получу "CcC", то файл будет обрабатываться как

line 1: _____
    ...
# for AAA
#export CONFIG = AAA_defconfig

# for BBB, BbB, Bbb, BBb3
#export CONFIG = BBB_defconfig

# for CCC, CcC, Ccc, Ccc1
export CONFIG = CCC_defconfig
    ...
other lines

Какой хороший способ сделать это в Python?

Заранее спасибо !!

Ответы [ 4 ]

1 голос
/ 22 октября 2010

Сначала создайте функцию генератора:

import re
def uncomment(seq, prev_pattern, curr_pattern):
    """Remove comment from any string in seq matching curr_pattern if the previous line matches prev_pattern"""
    prev = ""
    for curr in seq:
        if re.match(curr_pattern, curr) and re.match(prev_pattern, prev):
            yield curr[1:]
    else:
       yield curr
    prev = curr

Теперь проверьте это:

>>> lines = ["leave this alone", "#fix next line", "#fix this line", "leave this alone"]
>>> print "\n".join(uncomment(lines, "^#fix next", "^#fix this"))
leave this alone
#fix next line
fix this line
leave this alone

Теперь используйте его, чтобы исправить ваш файл:

with open(input_filename, 'r') as f_in:
    with open(output_filename, 'w') as f_out:
        for line in uncomment(f_in, "^#for AAA", "^#export CONFIG"):
            f_out.write(line)
1 голос
/ 21 октября 2010
def select_export(text, source, destination):
    uncomment_next = False
    for line in source:
        line = line.strip()
        if line.startswith('# for ') and text in set(t.strip() 
                for t in line[6:].split(',')):
            uncomment_next = True
        elif line.startswith('#') and uncomment_next:
            line = line[1:]
            uncomment_next = False
    destination.write(line + '\n')



with open('source') as f:
    with open('destination', 'w') as w:
        select_export('CcC', f, w)
1 голос
/ 22 октября 2010

Немного чище, более читабельный подход ИМО.

(И, да, чтобы изменить одну строку в файле, вы должны перезаписать и переписать весь файл.)

#!/usr/bin/env python2.7
import re

def find_and_modify(config_file, given_string):

    with open(config_file) as f:
        lines = f.readlines()

    given_string_re = re.compile(r'# for .*{}'.format(given_string))

    # line #'s that start with either "export" or "#export"
    export_line_numbers = []
    # the line # containing the given_string we're searching for
    uncomment_line_number = None

    for i,line in enumerate(lines):
        if re.match(r'#?export', line):
            export_line_numbers.append(i)
            prev_line = lines[i-1]
            if given_string_re.match(prev_line):
                uncomment_line_number = i

    for i in export_line_numbers:
        if i == uncomment_line_number:
            lines[i] = re.sub(r'^#*', '', lines[i])
        else:
            lines[i] = re.sub(r'^#*', '#', lines[i])

    with open(config_file, 'w') as f:
        f.writelines(lines)

find_and_modify('some_file', 'AAA')
find_and_modify('some_file', 'CcC')
1 голос
/ 21 октября 2010

Тогда почему бы не сделать его как

line = 'xxxx'
CONFIG = default_deconfig

if line == 'AAA':
    CONFIG =  AAA_defconfig
elif line == 'CCC':
    CONFIG =  CCC_defconfig
...

, если только это не файл python и вы не хотите им манипулировать.Это выглядит так.

В этом случае создайте генератор конфигурации, который будет создавать файл конфигурации на основе строковой переменной.

[Редактировать: На основе комментариев]

Вывозможно, придется внести некоторые коррективы, но это должно сработать.

# Simple , crude solution

f = open('file1', 'r')
manipulated_lines = []
readFirstLine = False
config = ''
configComma = ''
uncommentLine = 0
for line in f:
    tokens = line.split()

    if uncommentLine == 1:
        # this is comment line
        if tokens[0] == '#export':
            manipulated_lines.append(line[1:])
            uncommentLine = uncommentLine + 1
            continue
    elif uncommentLine > 1:
        manipulated_lines.append(line)
        continue

    if not readFirstLine: 
        config = line.rstrip('\n')
        configComma = config + ','
        readFirstLine = True

    # Process additional lines 
    manipulated_lines.append(line)

    if len(tokens) > 0 and tokens[0] == '#':
        if tokens[1] == 'for':
            if config in tokens or configComma in tokens:
                uncommentLine = uncommentLine + 1
                continue

print manipulated_lines
f.close()
fw = open('file2', 'w')
fw.writelines(manipulated_lines)
fw.close()

Вход: файл1

CCC
# for AAA
#export CONFIG = AAA_defconfig

# for BBB, BbB, Bbb, BBb3
#export CONFIG = BBB_defconfig

# for CCC, CcC, Ccc, Ccc1
#export CONFIG = CCC_defconfig
   ...

Выход: файл2

CCC
# for AAA
#export CONFIG = AAA_defconfig

# for BBB, BbB, Bbb, BBb3
#export CONFIG = BBB_defconfig

# for CCC, CcC, Ccc, Ccc1
export CONFIG = CCC_defconfig
   ...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...