2013-04-04 21 views

Odpowiedz

20

Czytasz dane binarne, nie str, więc trzeba rozszyfrować wyjście pierwsze. Jeśli ustawisz universal_newlines argument True, następnie stdout jest automatycznie dekodowane przy użyciu wynik locale.getpreferredencoding() method (tak samo jak w przypadku otwierania plików tekstowych):

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]) 

Jeśli używasz Pythona 3.6 lub nowszy, można użyć jawne encoding argumentem na wezwanie Popen() do określenia innego kodeka użyć, jak, na przykład, 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]) 

Jeśli trzeba użyć innego kodeka w Pythonie 3.5 lub wcześniej, nie używaj universal_newlines , właśnie Dec Odtworzyć tekst z bajtów jawnie.

Próbowałeś podzielić wartość bytes użyciu str argumentu:

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

Dzięki dekodowaniu można uniknąć tego problemu, a połączenie print() nie będą musiały poprzedzić wyjście z b'..' albo.

Jednakże, prawdopodobnie po prostu chcesz zamiast użyć modułu os aby uzyskać informacje filesystem:

import os 

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

Dzięki nim działa, ale każdy pomysł, dlaczego otrzymuję indeks listy poza zasięgiem błędu –

+0

@NickLoach: linia ma mniej niż 3 kolumny? –

+0

Dzięki Martijn linia ma ['03 -04-2013 ',' ', '19: 48', '', '', '', '

', '', '', '', '', ' ',' ',' ',' ',' ',' .ipython \ r \ n '] Chcę, aby feild nazwany .ipython jako wyjście –

0

Lepsze wykorzystanie binascii.b2a_uu który konwertuje dane binarne do linii znaków ASCII

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

prostsze rozwiązanie pierwszej części Martijn Pieters's answer ma przekazać argument universal_newlines=True do wywołania Popen.

bym nawet uproszczenie tego:

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

UWAGA: Jeśli nazwy pliku lub katalogu zawiera spacje, należy os.listdir('.') jak zasugerowano w Martijn Pieters's answer czy coś następujących:

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' jest wewnętrzną komendą w systemie Windows, tzn. Jeśli nie ma' dir.exe', wtedy 'shell = True' jest w tym przypadku potrzebna. – jfs

+0

@ J.F.Sebastian, dzięki za wskazanie tego! – tjanez

+0

Jeśli przyjmiemy dane wyjściowe z jedną kolumną, wówczas można użyć '.splitlines()' do obsługi ścieżek ze spacjami – jfs

Powiązane problemy