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

在python中使用sed将单行模式替换为多行,python,sed,Python,Sed,这在test.txt中 swift ring builder account.builder添加zZONE-STORAGE\u LOCAL\u NET\u IP:6002/设备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/

这在test.txt中

swift ring builder account.builder添加zZONE-STORAGE\u LOCAL\u NET\u IP:6002/设备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不会与
/
混淆


请建议使用
子流程
或任何其他方式(如
os.system(cmd)
不要使用
sed
);使用替换文件中的行:

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)

这将在名为
文件名
的文件上循环,并按原样重新写入每一行,除非该行等于
'swift-ring-builder account.builder add zZONE-STORAGE\u LOCAL\u NET\u IP:6002/DEVICE 100'
,在这种情况下会写入三行不同的行。

不要使用
sed
;使用替换文件中的行:

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\u LOCAL\u NET\u IP:6002/DEVICE 100'
,在这种情况下,会写入三行不同的代码。

您可以使用正则表达式替换
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)
pattern=r'^(swift环生成器)帐户(.builder add)zZONE-STORAGE\u LOCAL\u NET\u IP:6002/设备100$'
替换='\\gaccount\\gz1-10.0.0.2:6002/sda 100\n'\
“\\gcontainer\\gz1-10.0.0.2:6001/sda 100\n”\
“\\gobject\\gz1-10.0.0.2:6000/sda 100\n”
newstr=re.sub(模式、替换、旧模式)
看一看


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

您可以使用正则表达式替换
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)
pattern=r'^(swift环生成器)帐户(.builder add)zZONE-STORAGE\u LOCAL\u NET\u IP:6002/设备100$'
替换='\\gaccount\\gz1-10.0.0.2:6002/sda 100\n'\
“\\gcontainer\\gz1-10.0.0.2:6001/sda 100\n”\
“\\gobject\\gz1-10.0.0.2:6000/sda 100\n”
newstr=re.sub(模式、替换、旧模式)
看一看


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

为什么不使用Python中的
re
模块呢?@MartijnPieters嗨,Martijn,我是新手,你能指定如何使用
re
模块吗?我还不清楚你的输入将如何导致你的输出。您没有包括您的
oldstr
newstr
值。
oldstr=swift ring builder account.builder add zZONE-STORAGE\u LOCAL\u NET\u IP:6002/DEVICE 100
和newstr是上述3个多行,在这种情况下,您甚至不需要使用正则表达式;只需用3行新行替换匹配行来重写文件。我在下面写了一个答案。为什么不使用Python中的
re
模块呢?@MartijnPieters嗨,Martijn,我是新手,你能指定如何使用
re
模块吗?我还不清楚你的输入将如何导致你的输出。您没有包括您的
oldstr
newstr
值。
oldstr=swift ring builder account.builder add zZONE-STORAGE\u LOCAL\u NET\u IP:6002/DEVICE 100
和newstr是上述3个多行,在这种情况下,您甚至不需要使用正则表达式;只需用3行新行替换匹配行来重写文件。我在下面写了一个答案,这个答案就是这样的;OP希望用文字文本将1行替换为3行;OP希望用文字文本将1行替换为3行。