2014-01-06 39 views
0

這是test.txt的使用由在python多行替換單個線圖案SED

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 

在我以前#,因爲我的模式containes /,所以我用了#分隔符,使SED不/

混淆,請建議使用subprocess或類似os.system(cmd)

任何其他方式解決的子進程
+2

爲什麼不使用Python中的「re」模塊呢? –

+0

@MartijnPieters你好Martijn,我是新手,你可以指定如何使用're'模塊 – Capricorn

+0

你的輸入將如何導致你的輸出是很不清楚的。你沒有包含你的'oldstr'和'newstr'的​​值。 –

回答

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',在這種情況下,三種不同的線被寫入。

+0

奇妙的工作!謝謝@Martijn :) – Capricorn

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的方法。

+0

這隻產生** ** **行; OP希望用3個不同的行代替1行,並帶有文本文本。 –

+0

謝謝,讓我們修改更換... –