2012-10-03 42 views
9

Có cách nào, mà không có một vòng lặp đôi để thực hiện những gì lệnh sed sau khôngpython tương đương với sed

Input:

Time 
Banana 
spinach 
turkey 

sed -i "/Banana/ s/$/Toothpaste/" file

Output:

Time 
BananaToothpaste 
spinach 
turkey 

Những gì tôi có cho đến nay là một danh sách đôi mà sẽ mất một thời gian dài để đi thông qua cả hai.

Danh sách một có một loạt các con số danh sách b có các bó cùng một số nhưng theo một thứ tự khác nhau

Đối với mỗi mục trong Một tôi muốn tìm dòng trong B với cùng số và gia tăng giá trị C đến cuối của nó.

Hy vọng điều này có ý nghĩa, ngay cả khi ví dụ của tôi không có.

Tôi đã làm như sau trong Bash và tuy nhiên nó đã làm việc đó là siêu chậm ...

for line in $(cat DATSRCLN.txt.utf8); do 
     srch=$(echo $line | awk -F'^' '{print $1}'); 
     rep=$(echo $line | awk -F'^' '{print $2}'); 
     sed -i "/$(echo $srch)/ s/$/^$(echo $rep)/" tmp.1; 
done 

Cảm ơn!

+3

dụ sed của bạn không tương đương với những gì bạn đang thực sự cố gắng để làm. –

+0

Vì vậy, trong bash tôi đã làm điều này và nó đã được làm việc, nhưng siêu chậm ... – user1601716

+0

bạn thực sự có thể chạy sed trong python bằng cách sử dụng lệnh 'subprocess'. – karthikr

Trả lời

9

Sử dụng re.sub():

newstring = re.sub('(Banana)', r'\1Toothpaste', oldstring) 

này bắt một nhóm (giữa dấu ngoặc đơn đầu tiên), và thay thế nó bằng chính nó (phần \ số) tiếp theo là một hậu tố mong muốn. Nó là cần thiết để sử dụng r'' (chuỗi thô) để thoát được giải thích một cách chính xác.

0

Có thể làm điều này bằng tập tin tmp với yêu cầu hệ thống thấp và chỉ có một lần lặp mà không cần sao chép toàn bộ tập tin vào bộ nhớ:

#/usr/bin/python 
import tempfile 
import shutil 
import os 

newfile = tempfile.mkdtemp() 
oldfile = 'stack.txt' 

f = open(oldfile) 
n = open(newfile,'w') 

for i in f: 
     if i.find('Banana') == -1: 
       n.write(i) 
       continue 

     # Last row 
     if i.find('\n') == -1: 
       i += 'ToothPaste' 
     else: 
       i = i.rstrip('\n') 
       i += 'ToothPaste\n' 

     n.write(i) 

f.close() 
n.close() 

os.remove(oldfile) 
shutil.move(newfile,oldfile) 
2

Nếu bạn đang sử dụng Python3 các module sau đây sẽ giúp bạn: https://github.com/mahmoudadel2/pysed

wget https://raw.githubusercontent.com/mahmoudadel2/pysed/master/pysed.py 

Đặt file module vào Python3 bạn module con đường, sau đó:

import pysed 
pysed.replace(<Old string>, <Replacement String>, <Text File>) 
pysed.rmlinematch(<Unwanted string>, <Text File>) 
pysed.rmlinenumber(<Unwanted Line Number>, <Text File>) 
1

Bạn thực sự có thể gọi sed từ python. Nhiều cách để làm điều này nhưng tôi thích sử dụng mô-đun sh. (yum -y install python-sh)

Kết quả của chương trình ví dụ của tôi là sau.

[[email protected] sh]$ cat input 
Time 
Banana 
spinich 
turkey 
[[email protected] sh]$ python test_sh.py 
[[email protected] sh]$ cat input 
Time 
Toothpaste 
spinich 
turkey 
[[email protected] sh]$ 

Đây là test_sh.py

import sh 

sh.sed('-i', 's/Banana/Toothpaste/', 'input') 

này có thể sẽ chỉ làm việc dưới LINUX.

3

Một lính muộn để cuộc đua, đây là thực hiện của tôi cho sed bằng Python:

import re 
import shutil 
from tempfile import mkstemp 


def sed(pattern, replace, source, dest=None, count=0): 
    """Reads a source file and writes the destination file. 

    In each line, replaces pattern with replace. 

    Args: 
     pattern (str): pattern to match (can be re.pattern) 
     replace (str): replacement str 
     source (str): input filename 
     count (int): number of occurrences to replace 
     dest (str): destination filename, if not given, source will be over written.   
    """ 

    fin = open(source, 'r') 
    num_replaced = count 

    if dest: 
     fout = open(dest, 'w') 
    else: 
     fd, name = mkstemp() 
     fout = open(name, 'w') 

    for line in fin: 
     out = re.sub(pattern, replace, line) 
     fout.write(out) 

     if out != line: 
      num_replaced += 1 
     if count and num_replaced > count: 
      break 
    try: 
     fout.writelines(fin.readlines()) 
    except Exception as E: 
     raise E 

    fin.close() 
    fout.close() 

    if not dest: 
     shutil.move(name, source) 

ví dụ:

sed('foo', 'bar', "foo.txt") 

sẽ thay thế tất cả 'foo' với 'bar' trong foo.txt

sed('foo', 'bar', "foo.txt", "foo.updated.txt") 

sẽ thay thế tất cả 'foo' bằng 'bar' thành 'foo.txt' và lưu kết quả vào "foo.updated.txt".

sed('foo', 'bar', "foo.txt", count=1) 

sẽ thay thế chỉ xuất hiện đầu tiên của 'foo' với 'bar' và lưu kết quả trong file gốc 'foo.txt'

Các vấn đề liên quan