使用sed在python中用多行替换单行模式

时间:2014-01-06 12:02:42

标签: python sed

这是在test.txt

swift-ring-builder account.builder add zZONE-STORAGE_LOCAL_NET_IP:6002/DEVICE 100

我想用sed在python中用多行替换上面的行,以便上面的行成为:

swift-ring-builder account.builder add z1-10.0.0.2:6002/sda 100
swift-ring-builder container.builder add z1-10.0.0.2:6001/sda 100
swift-ring-builder object.builder add z1-10.0.0.2:6000/sda 100

我用过:

import subprocess

def search_and_replace_pattern(oldstr, newstr, path):
    subprocess.call(['sed', '-i', 's#'+oldstr+'#'+newstr+'#', path])

但后来我得到了:

sed: -e expression #1, char 88: unterminated `s' command

在我使用#的子流程中,因为我的模式包含/,所以我使用了#分隔符,因此sed不会与/混淆

请使用subprocess或任何其他方式os.system(cmd)

建议解决方案

2 个答案:

答案 0 :(得分:2)

不要使用sed;使用fileinput module代替文件中的行:

import fileinput
import sys

for line in fileinput.input(filename, inplace=True):
    if line.strip() == 'swift-ring-builder account.builder add zZONE-STORAGE_LOCAL_NET_IP:6002/DEVICE 100':
        sys.stdout.write(
            'swift-ring-builder account.builder add z1-10.0.0.2:6002/sda 100\n'
            'swift-ring-builder container.builder add z1-10.0.0.2:6001/sda 100\n'
            'swift-ring-builder object.builder add z1-10.0.0.2:6000/sda 100\n'
        )
    else:
        sys.stdout.write(line)

这循环遍历由filename命名的文件,重写原始的每一行,除非该行等于'swift-ring-builder account.builder add zZONE-STORAGE_LOCAL_NET_IP:6002/DEVICE 100',在这种情况下写入三行不同。

答案 1 :(得分:1)

您可以使用正则表达式替换oldstr中有问题的行:

pattern = r'^(swift-ring-builder )account(.builder add )zZONE-STORAGE_LOCAL_NET_IP:6002/DEVICE 100$'
replacement = '\\g<1>account\\g<2>z1-10.0.0.2:6002/sda 100\n' \ 
              '\\g<1>container\\g<2>z1-10.0.0.2:6001/sda 100\n' \
              '\\g<1>object\\g<2>z1-10.0.0.2:6000/sda 100\n'
newstr = re.sub(pattern, replacement, oldstr)

查看re module documentation

编辑。但是对于这个简单的任务,我个人更喜欢Martijn Pieters的方法。