2013-04-04 3 views

risposta

20

Stai leggendo i dati binari, non str, quindi è necessario per decodificare l'uscita prima. Se si imposta l'argomento universal_newlines-True, poi stdout viene decodificato automaticamente utilizzando il risultato del locale.getpreferredencoding() method (come per l'apertura di file di testo):

cmd = subprocess.Popen(
    'dir', shell=True, stdout=subprocess.PIPE, universal_newlines=True) 
for line in cmd.stdout: 
    columns = line.decode().split() 
    if columns: 
     print(columns[-1]) 

Se si utilizza Python 3.6 o più recente, è possibile utilizzare un esplicito encoding argomento per la chiamata Popen() per specificare un codec diverso da usare, come, per esempio, UTF-8:

cmd = subprocess.Popen(
    'dir', shell=True, stdout=subprocess.PIPE, encoding='utf8') 
for line in cmd.stdout: 
    columns = line.split() 
    if columns: 
     print(columns[-1]) 

Se è necessario utilizzare un codec diverso in Python 3.5 o precedente, non usare universal_newlines , solo dec ode esplicitamente il testo dai byte.

si stava tentando di dividere un valore bytes utilizzando un argomento str:

>>> b'one two'.split(' ') 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: Type str doesn't support the buffer API 

Decodificando si evita questo problema, e la chiamata print() non dovrà anteporre l'uscita con b'..' sia.

Tuttavia, probabilmente vuole solo utilizzare il modulo os invece per ottenere informazioni filesystem:

import os 

for filename in os.listdir('.'): 
    print(filename) 
+0

Thanks it funziona, ma qualsiasi idea, perché sto ricevendo l'indice di lista fuori intervallo errore –

+0

@NickLoach: la linea ha meno di 3 colonne? –

+0

Grazie Martijn la linea ha ['03 -04-2013 ',' ', '19: 48', '', '', '', '

', '', '', '', '', ' ',' ',' ',' ',' ',' .ipython \ r \ n '] voglio il feild chiamato .ipython come output –

0

Migliore utilizzo binascii.b2a_uu che converte i dati binari in una riga di caratteri ASCII

from binascii import b2a_uu 
cmd = b2a_uu(subprocess.Popen('dir',shell=True,stdout=subprocess.PIPE)) 
4

Un semplice la soluzione della prima parte di Martijn Pieters's answer consiste nel passare l'argomento universal_newlines=True alla chiamata Popen.

Vorrei anche semplificare questo a:

output = subprocess.check_output('dir', universal_newlines=True) 
columns = output.split() 
print(columns) 

NOTA: Se i nomi di file o directory contengono spazi, utilizzare os.listdir('.') come suggerito in Martijn Pieters's answer o qualcosa di simile al seguente:

output = subprocess.check_output('dir', universal_newlines=True) 
columns = [] 
for e in output.split(): 
    if len(columns) > 0 and columns[-1].endswith('\\'): 
     columns[-1] = columns[-1][:-1] + " " + e 
    else: 
     columns.append(e) 
print(columns) 
+0

'dir' è un comando interno su Windows, ad esempio, se non è presente' dir.exe', allora in questo caso 'shell = True' è necessario. – jfs

+0

@ J.F.Sebastian, grazie per avermelo fatto notare! – tjanez

+0

Se assumiamo un output a una colonna, potresti usare '.splitlines()', per gestire i percorsi con spazi – jfs