[英]How to replace one field of a line by another line in awk/sed/python?
input.txt中
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,並將函數名稱視為鍵,將其參數視為值。 實施並不那么容易。
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
。
這是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()
設線為輸入文件的行。 如果所有參數都是整數或函數名,則以下代碼將起作用
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))
)
可能有很多方法可以做到這一點,但我認為這是一種簡單的方法來做你想要的。
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
如果你的文件是這樣的
A(0,1,2)
B(A,3)
C(B,4,5)
使用python:
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)']
我不明白...在每個備用行中,如果它在那里告訴我我可以編輯代碼。
有點長但更模塊化:
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)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.