在python中使用sed通过subprocess.call进行文件替换

时间:2014-04-24 16:13:13

标签: python bash sed subprocess

我在一个文件中有一个列,我想用另一个文件中的列替换。我正在尝试使用sed在python中执行此操作,但我不确定我是否正确执行此操作。也许代码会让事情变得更清晰:

 20 for line in infile1.readlines()[1:]:
 21         element = re.split("\t", line)
 22         IID.append(element[1])
 23         FID.append(element[0])
 24 
 25 os.chdir(binary_dir)
 26 
 27 for files in os.walk(binary_dir):
 28         for file in files:
 29                 for name in file:
 30                         if name.endswith(".fam"):
 31                                 infile2 = open(name, 'r+')
 32 
 33 for line in infile2.readlines():
 34         parts = re.split(" ", line)
 35         Part1.append(parts[0])
 36         Part2.append(parts[1])
 37 
 38 for i in range(len(Part2)):
 39         if Part2[i] in IID:
 40                 regex = '"s/\.*' + Part2[i] + '/' + Part1[i] + ' ' + Part2[i] + '/"' + ' ' + phenotype 
 41                 print regex
 42                 subprocess.call(["sed", "-i.orig", regex], shell=True)

这就是打印正则表达式所做的。系统似乎在sed进程中挂起,因为它在那里停留了很长时间而没有做任何事情。

"s/\.*131006/201335658-01 131006/" /Users/user1/Desktop/phenotypes2

感谢您的帮助,如果您需要进一步澄清,请告诉我们!

2 个答案:

答案 0 :(得分:1)

如果您拥有Python和sed模块,则不需要re。以下是如何使用re替换字符串中给定模式的示例。

>>> import re
>>> line = "abc def ghi"
>>> new_line = re.sub("abc", "123", line)
>>> new_line
'123 def ghi'
>>> 

当然,这只是Python中的一种方法。我觉得对你来说str.replace()也会做这件事。

答案 1 :(得分:1)

第一个问题是shell=True,它与list参数一起使用。要么删除shell=True,要么使用字符串参数(完整的shell命令):

from subprocess import check_call

check_call(["sed", "-i.orig", regex])

否则参数('-i.orig'regex)会传递给/bin/sh而不是sed

第二个问题是你没有提供输入文件,因此sed期望来自stdin的数据,这就是它似乎挂起的原因。

如果您想对文件进行更改,可以使用fileinput module

#!/usr/bin/env python
import fileinput

files = ['/Users/user1/Desktop/phenotypes2'] # if it is None it behaves like sed
for line in fileinput.input(files, backup='.orig', inplace=True):
    print re.sub(r'\.*131006', '201335658-01 13100', line),

fileinput.input()将stdout重定向到当前文件,即print更改文件。

逗号设置sys.stdout.softspace以避免重复的换行符。