使用Python修改ssh上的文本文件 - 性能

时间:2014-02-15 17:51:17

标签: python performance ssh sed

我需要通过ssh替换文本文件中的某些行,如果它们包含某个键字符串。我为此编写了以下简单的Python函数:

def ssh_edit_file(h, u, file_in, file_out, key, new): 
    import paramiko, string, os

    c_out = []

    ssh = paramiko.SSHClient()
    ssh.load_system_host_keys(os.environ["HOME"] + "/.ssh/known_hosts")
    ssh.connect(h,username=u)
    ftp = ssh.open_sftp()

    f_in = ftp.file(file_in, "r")
    c_in = f_in.readlines()
    for line in c_in:
        if string.find(line, key) > 0:
            c_out.append(new + '\n')
        else:
            s = line
            c_out.append(s)

   f_out = ftp.file(file_out, "w")
   f_out.writelines(c_out)

   f_in.close()
   f_out.close()
   ftp.close()
   ssh.close()

这有点慢,这对我的大多数文件来说都没问题。如果我将它用于较大的文件(~2k行),速度就成了问题。有什么办法可以轻松加快速度?

1 个答案:

答案 0 :(得分:0)

使用的想法对我的案例很有用。作为回报有用的建议,我喜欢共享解决方案:

def ssh_edit_file(h, u, file_in, file_out, key, new):
    """
    SSH_EDIT_FILE - replace a line in a remote file
    """ 

    import warnings

    try:
        s = new.replace("'","\'")
        if file_in == file_out:
            ssh_exe('sed -i "s/.*' + key + '.*/' + s + '/g" ' + file_out,
                    h = h, u = u )
        else:
            ssh_exe('sed -e "s/.*' + key + '.*/' + s + '/g" ' + 
                    file_in + '>|' +  file_out,
                    h = h, u = u )
    except:
        warnings.warn('key not found')

def ssh_exe(cmd, client=None, h=None,u=None):
    """
    SSH_EXE - Run command via ssh
    """

    import paramiko, os

    if h:
        if client:
              raise RuntimeError('Please specify either client of h and u')
        client = paramiko.SSHClient()
        client.load_system_host_keys(os.environ["HOME"] + "/.ssh/known_hosts")
        client.connect(h,username=u)
    else:
        if h or u:
              raise RuntimeError('Please specify either client of h and u')

    stdin, stdout, stderr = client.exec_command(cmd)

    if stdout.channel.recv_exit_status():
        e = stderr.readlines()
        if not e == []:
            raise RuntimeError('Error in executing ' + cmd + '\n'.join(e))

    if h:
        client.close()