2017-03-13 102 views
0

我想通過搜索字符串開頭的特定字母來替換文件中的文本。例如,下面是該文件的一個部分:替換以某些字符開頭的文件中的文本字符串

6 HT  4.092000 4.750000 -0.502000  0  5  7 
7 HT  5.367000 5.548000 -0.325000  0  5  6 
8 OT -5.470000 5.461000 1.463000  0  9 10 
9 HT -5.167000 4.571000 1.284000  0  8 10 
10 HT -4.726000 6.018000 1.235000  0  8  9 
11 OT -4.865000 -5.029000 -3.915000  0 12 13 
12 HT -4.758000 -4.129000 -3.608000  0 11 13 

我想用「HT」作爲搜索,並能與2002年取代「space0space」當我嘗試我更換所有0與2002年和而不是隻是0的列。之後,我需要然後搜索「OT」並用2001替換0列。

所以基本上我需要搜索一個字符串來標識行並替換列特定字符串介於兩者之間的文字是可變的。輸出需要打印到new_file.xyz。另外,我會在很多文件上重複這樣做,所以將它作爲可以在文件前面輸入的腳本將很棒。謝謝。

+0

請提供你已經嘗試做 – nir0s

+0

對不起這沒有保留文件格式。 – Drewucla

+0

這裏是我所做的,但我無法指定搜索部分來查找HT ..#!/ usr/bin/perl use strict; 使用警告; $^I ='.bak'; #創建備份副本 while(<>){ s/0/2002/g; #做替換 打印; #打印到修改後的文件 } – Drewucla

回答

0

這應該爲你(用於HT)做到這一點:

with open('file.txt') as f: 
    lines = f.readlines() 

new_lines = [] 

for line in lines: 
    if "HT" in line: 
     new_line = line.replace(' 0 ', '2002') 
     new_lines.append(new_line) 
    else: 
     new_lines.append(line) 


content = ''.join(new_lines) 
print(content) 


# 6 HT  4.092000 4.750000 -0.502000 2002 5  7 
# 7 HT  5.367000 5.548000 -0.325000 2002 5  6 
# 8 OT -5.470000 5.461000 1.463000  0  9 10 
# 9 HT -5.167000 4.571000 1.284000 2002 8 10 
# 10 HT -4.726000 6.018000 1.235000 2002 8  9 
# 11 OT -4.865000 -5.029000 -3.915000  0 12 13 
# 12 HT -4.758000 -4.129000 -3.608000 2002 11 13 

重複相同的邏輯(增加的情況下或其他方式)的其他線路標識符。

如果你把這個功能,你可以使用它的ID來替換所有:

def _find_and_replace(current_lines, line_id, value): 
    lines = [] 
    for l in current_lines: 
     lines.append(l.replace(' 0 ', value)) if line_id in l else lines.append(l) 
    return ''.join(lines) 


with open('file.txt') as f: 
    lines = f.readlines() 
    new_lines = _find_and_replace(lines, line_id='HT', value='2002') 
    print(new_lines) 

不過,如果你有很多的標識符,我將實現一個解決方案,它不會在列表中去每次都是行,而是在迭代行時查找標識符。

+0

當我嘗試這個時,我得到錯誤。我試圖使腳本rep_0_2002.py成爲#!/ usr/bin/perl use strict; 使用警告; $^I ='.bak'; #創建備份副本 張開(<>)爲f: 線= f.readlines() new_lines = [] 用於行的行: 如果線 「HT」: NEW_LINE =行。替換('0','2002') new_lines。追加(NEW_LINE) 其他: new_lines.append(線) 含量=「」。加入(new_lines) 打印(內容) – Drewucla

+0

我沒有得到這個工作,但它只是打印在屏幕上,我需要它打印到一個新的文件。我如何獲得它打印到一個新的文件? – Drewucla

0

使用fileinput模塊,re.search()re.sub()功能的解決方案:

import fileinput, re 

with fileinput.input(files=("lines.txt"), inplace=True) as f: 
    for line in f: 
     if (re.search(r'\bHT\b', line)): # checks if line contains `HT` column 
      print(re.sub(r' 0 ', '2002', line).strip()) 
     elif (re.search(r'\OT\b', line)): # checks if line contains `OT` column 
      print(re.sub(r' 0 ', '2001', line).strip()) 
     else: 
      print(line) 

處理後的文件內容:

6 HT  4.092000 4.750000 -0.502000 2002 5  7 
7 HT  5.367000 5.548000 -0.325000 2002 5  6 
8 OT -5.470000 5.461000 1.463000 2001 9 10 
9 HT -5.167000 4.571000 1.284000 2002 8 10 
10 HT -4.726000 6.018000 1.235000 2002 8  9 
11 OT -4.865000 -5.029000 -3.915000 2001 12 13 
12 HT -4.758000 -4.129000 -3.608000 2002 11 13 

Optional in-place filtering: if the keyword argument inplace=True is passed to fileinput.input() or to the FileInput constructor, the file is moved to a backup file and standard output is directed to the input file (if a file of the same name as the backup file already exists, it will be replaced silently). This makes it possible to write a filter that rewrites its input file in place.

+0

你好RomanPerekhrest。當我嘗試這個時,我得到錯誤:運算符預計在/home/adutton/python_scripts/rep_0_20012.py第10行,在「附近」的「Bareword」爲「 \t(之前缺少運算符?) 無法修改標量中的常量項在/home/adutton/python_scripts/rep_0_20012.py第10行,在「附近」,「 語法錯誤在/home/adutton/python_scripts/rep_0_20012.py第10行,附近」),因爲f「 r'at /home/adutton/python_scripts/rep_0_20012.py第12行。 – Drewucla

+0

以下是我試過的腳本:#!/ usr/bin/perl use strict; 使用警告; $^I ='.bak'; #創建一個備份副本 進口的FileInput,重新 與fileinput.input(文件=( 「lines.txt」),就地= TRUE)爲f: 線路在F: 如果(re.search(R」 (r'0','2002',line).strip()) elif(re.search(r(')'):#檢查行是否包含'HT'列 print '\ OT \ b',行)):#檢查行是否包含'OT'列 print(re.sub(r'0','2001',line).strip()) else: print ) – Drewucla

+0

@Drewucla,我認爲你在代碼中犯了一些錯誤。它應該工作正常。什麼是Python版本? – RomanPerekhrest