2010-10-21 96 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)