2010-10-21 137 views
1

我有一个文件,如下所示:蟒蛇取消对行权

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中做到这一点的好方法?

在此先感谢!

回答

1

那么为什么不把它作为

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() 

输入:file1的

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 
    ... 

输出:file2的

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 
    ... 
+0

嗨,pyfunc,要操纵的文件根本不是一个py文件,它只是一个普通的txt文件,它给出了,我只能修改它。 – pepero 2010-10-21 17:25:33

+0

@pepero:我对此感到困惑。在这种情况下,nosklo的答案就足够了。这正是你想要的。 – pyfunc 2010-10-21 17:27:10

+0

请参阅我对他的解决方案的评论。无论如何,pyfunc,感谢您的意见。 – pepero 2010-10-21 17:39:20

1
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) 
+0

嗨,nosklo,感谢您的意见。但是,您的解决方案有以下问题:1)我需要先找到'CONFIG'行,然后检查上一行是否有'文本'。您的解决方案假定文件中没有其他类型的'#用于文本'。 2)最重要的是,也是我最想知道的是,是否可以在不重写python中的whoe文件的情况下更改该行?谢谢你们一样! – pepero 2010-10-21 17:36:17

1

一点清洁器更具有可读性方法IMO。

(是的,修改一个文件中的一行,你必须覆盖和重写整个文件。)

#!/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

首先创建一个生成器功能:

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)