43

Python から SSH を使用してサーバーからファイルを読み込もうとしています。Paramikoを使って接続しています。サーバーに接続して次のようなコマンドを実行し、サーバーcat filenameからデータを取得できますが、読み取ろうとしているファイルのサイズは約 1 GB 以上です。

Pythonを使用してサーバー上のファイルを1行ずつ読み取るにはどうすればよいですか?

追加情報: 定期的に行うことは、cat filenameコマンドを実行して結果を変数に格納し、それを処理することです。しかし、ここにあるファイルは非常に大きいため、サーバーからファイルを 1 行ずつ読み取る方法を探しています。

編集: 一連のデータを読み取って行に分割することはできますが、問題は、バッファーで受信したデータに必ずしも完全な行が含まれているとは限らないことです。たとえば、バッファに 300 行ある場合、最後の行はサーバー上の行の半分にすぎず、次の半分はサーバーへの次の呼び出しで取得されます。完全な線が欲しい

編集 2: ファイル内の特定の範囲の行を出力するために使用できるコマンドは何ですか。最初の 100 行を印刷し、次に次の 100 行などを印刷するように? このようにして、バッファには常に完全な行が含まれます。

4

5 に答える 5

77

Paramiko のSFTPClientクラスを使用すると、ファイルのようなオブジェクトを取得して、Pythonic の方法でリモート ファイルからデータを読み取ることができます。

開いていると仮定しますSSHClient

sftp_client = ssh_client.open_sftp()
remote_file = sftp_client.open('remote_filename')
try:
    for line in remote_file:
        # process line
finally:
    remote_file.close()
于 2009-10-20T22:53:20.787 に答える
13

fabricを使用した@Matt Good の answer の拡張は次のとおりです。

from fabric.connection import Connection

with Connection(host, user) as c, c.sftp() as sftp,   \
         sftp.open('remote_filename') as file:
    for line in file:
        process(line)

古いファブリック 1 の回答:

from contextlib     import closing
from fabric.network import connect

with closing(connect(user, host, port)) as ssh, \
     closing(ssh.open_sftp()) as sftp, \
     closing(sftp.open('remote_filename')) as file:
    for line in file:
        process(line)
于 2009-10-21T03:15:19.340 に答える
7
#!/usr/bin/env python
import paramiko
import select
client = paramiko.SSHClient()
client.load_system_host_keys()
client.connect('yourhost.com')
transport = client.get_transport()
channel = transport.open_session()
channel.exec_command("cat /path/to/your/file")
while True:
  rl, wl, xl = select.select([channel],[],[],0.0)
  if len(rl) > 0:
      # Must be stdout
      print channel.recv(1024)
于 2009-10-20T20:12:03.390 に答える
4

「行ごと」とはどういう意味ですか。ネットワーク ホスト間には多くのデータ バッファがあり、どれも行指向ではありません。

したがって、一連のデータを読み取ってから、近端でそれを行に分割できます。

ssh otherhost cat somefile | python process_standard_input.py | do_process_locally

または、プロセスに遠端で一連のデータを読み取らせ、それを分割し、行ごとにフォーマットして送信することもできます。

scp process_standard_input.py otherhost
ssh otherhost python process_standard_input.py somefile |  do_process_locally

私が気にする唯一の違いは、限られたネットワーク パイプを介してデータの量をどのように削減するかということです。あなたの状況では、それは重要かもしれませんし、重要でないかもしれません。

一般にcat、SSH パイプを使用してギガバイトのデータを移動することに問題はありません。

于 2009-10-20T20:11:21.893 に答える