2014-11-05 90 views
2

input.txt中如何用awk/sed/python中的另一行替换一行的一个字段?

A(0,1,2) 
... 
B(A,3) 
... 
C(B,4,5) 

如果一个函数的第一个参数不等于0,但对应于函数名,我想所有的相应函数的参数来代替它(如更换第一上面的函数B中的参数'A'和函数A的所有参数)。这是期望

output.txt的

A(0,1,2) 
... 
B(0,1,2,3) 
... 
C(0,1,2,3,4,5) 

我们怎样才能做到这一点使用awk/SED或Python?

编辑:

一个想法我已经是函数名保存为变量,其作为在bash值的参数。在python中,我们可以使用dict,并将函数名称视为键,并将其参数视为值。实施并不容易。

+0

这......也有在输入文件???? – Hackaholic 2014-11-05 23:58:57

回答

3

在awk

awk -F'[()]' ' 
    $2 !~ /^0,/ { 
     split($2, a, /,/) 
     sub(/^[^,]+/, val[a[1]], $2) 
    } 
    { 
     val[$1] = $2 
     print $1 "(" $2 ")" 
    } 
' input.txt > output.txt 

sub(/^[^,]+/, val[a[1]], $2)用于将第一参数在$2匹配,并用其通过的执行中定义的的val[a[1]]值替换它val[$1] = $2上一行。

1

下面是一个Python的解决方案:

import re 

with open('input.txt') as f: 
    data = f.read() 
data = [line.strip() for line in data.split('\n') if line] 
sets, output = {}, open('output.txt', 'w') 
for line in data: 
    if line == '...': 
     output.write(line + '\n') 
     continue 
    sets[line[0]] = line[2:-1] 
    output.write(line[0] + '(') 
    for char in line[2:-1]: 
     if re.match(r'[\d,]', char): 
      output.write(char) 
     else: 
      output.write(sets[char]) 
    output.write(')\n') 
output.close() 

相关文章:open()re

1

让行成为输入文件的行。如果所有的参数都是整数或functionname

funcs = {} 
for line in lines: 
    match = re.search('(.*)\((.*)\)', line) 
    if not match: 
     raise RuntimeError('Line does not match expectation') 
    function_name = match.group(1) 
    parameters = map(str.strip, match.group(2).split(',')) 
    parameter_list = [] 
    for parameter in parameters: 
     try: 
      parameter_list.append(int(parameter)) 
     except ValueError: 
      parameter_list.extend(funcs.get(parameter, [])) 
    funcs[function_name] = parameter_list 

for func_name, paras in sorted(funcs.items()): 
    print '{function}({parameters})'.format(
     function=func_name, 
     parameters=', '.join(map(str, paras)) 
    ) 
1

可能有一吨的方法可以做到这一点,但我认为这是一个简单的方法,做你想做的下面的代码将正常工作。

import re 
import sys 

def convertLine(line): 
    if re.match("^\\w{1}\(.*\)$", line) is None: 
     return line 
    retVal = re.sub("A", "0,1,2",line[1:]) 
    retVal = re.sub("B", "0,1,2,3",retVal) 
    retVal = re.sub("C", "0,1,2,3,4,5",retVal) 
    return line[0:1]+retVal 

def main(): 
    for line in sys.stdin.read().splitlines(): 
     print convertLine(line) 

if __name__ == "__main__": 
    main() 

用法:

python ReplaceProg.py < input.txt 
1

,如果你的文件是这样的使用

A(0,1,2) 
B(A,3) 
C(B,4,5) 

蟒蛇:

f = open('inpu_file.txt').readlines() 
f[0] = f[0].strip() 
for i,x in enumerate(f): 
    if i > 0: 
     f[i]=re.sub(f[i-1][0],",".join(re.findall('\d+',f[i-1])),x).strip() 
print f 

输出:

['A(0,1,2)', 'B(0,1,2,3)', 'C(0,1,2,3,4,5)'] 

我不明白......在每一个备用线路,如果它告诉我,我可以编辑代码。

1

有点儿长,但更模块化:

import re 

def build_dict(fobj): 
    d = dict() 
    for line in fobj: 
     match = re.match('^(\w)\((.*)\)', line) 
     fname = match.group(1) 
     fargs = match.group(2) 
     d[fname] = replace(fargs, d) 
    fobj.seek(0) # Reset cursor to start of file 
    return d 

def replace(s, d): 
    for each in d: 
     if each in s: 
      s = s.replace(each, d[each]) 
    return s 

def split_paren(s): 
    index = s.index('(') 
    return s[:index], s[index:] 

def write_replace(fobj, d): 
    outname = fobj.name[:-4] + '.out' 
    outfile = open(outname, 'w') 
    for line in fobj: 
     first, second = split_paren(line) 
     second = replace(second, d) 
     outfile.write(first + second) 
    outfile.close() 

if __name__ == '__main__': 
    with open('test.txt', 'r') as f: 
     d = build_dict(f) 
     write_replace(f, d) 
相关问题