Jak wyświetlić jedną nazwę pliku na linię wyjściową w systemie Linux?

229

Korzystam z ls -apolecenia, aby uzyskać nazwy plików w katalogu, ale dane wyjściowe są w jednym wierszu.

Lubię to:

.  ..  .bash_history  .ssh  updater_error_log.txt

Potrzebuję wbudowanej alternatywy, aby uzyskać nazwy plików, każdy w nowej linii, jak poniżej:

.  
..  
.bash_history  
.ssh  
updater_error_log.txt
fixxxer
źródło
3
ls ma wyświetlać listę do spożycia przez ludzi. Jeśli używasz ls w jakimkolwiek innym celu (np. Aby uzyskać listę plików w skrypcie do iteracji), z pewnością używasz niewłaściwego narzędzia.
Juliano,
2
@juliano - Faktycznie ma być używany przez skrypt Pythona. Dlaczego nazywasz to niewłaściwym narzędziem?
fixxxer,
1
@ fixxer W momencie, gdy potokujesz lsdo Pythona, lswyświetli jeden plik w wierszu, jak wyjaśniono w mojej odpowiedzi.
Peter G.
6
@fixxxer: Zatem rzeczywiście używasz go niewłaściwie. Formatuje listę dla danych wyjściowych w terminalu użytkownika. Może zastępować znaki specjalne w nazwie pliku, może pomijać znaki o specjalnym znaczeniu itp. Innymi słowy, ls formatuje listę dla użytkownika. Chcesz niesformatowane nazwy plików. Czy jest jakiś szczególny powód, dla którego nie korzystasz z modułu glob globalnego? docs.python.org/library/glob.html Istnieją również „fnmatch”, „dircache” i inne.
Juliano
@fixxer Czy rzeczywiście zrobiłeś lswyjście pythoni obserwowałeś wyjście w jednym wierszu w pythonie?
Peter G.

Odpowiedzi:

430

Użyj -1opcji (zwróć uwagę, że jest to „jedna” cyfra, a nie mała litera „L”), jak poniżej:

ls -1a

Najpierw jednak upewnij się, że masz lswsparcie -1. Coreutils GNU (zainstalowane na standardowych systemach Linux) i Solaris; ale w razie wątpliwości, należy użyć man lslub ls --helpczy sprawdzić dokumentację. Na przykład:

$ man ls
...
       -1     list one file per line.  Avoid '\n' with -q or -b
Bert F.
źródło
2
+1 Nie wiedziałem o -1 (-l tak (Ell nie jeden)) Pokazuje się na stronie podręcznika, ale cały czas czytam jako Ell :)
slashmais
@slashmais - Ach, dobra uwaga - łatwo pomylić. Wyjaśniłem w odpowiedzi.
Bert F
1
@dty: dla GNU masz to udokumentowane w ls --helpwyjściu ... zawsze zainstalowane ;-)
Tony Delroy
3
Szukałem w Google linux ls one file per linei to był najlepszy artykuł. Nie mogę uwierzyć, jak trudna jest wybrana odpowiedź lub że ta odpowiedź ma mniej głosów niż ta, która dała się złapać kotowi. ls -1ftw.
crantok
3
lsdomyślnie -1zachowuje się, gdy wyjście nie jest podłączone do terminala.
codeforester,
131

Tak, możesz łatwo zrobić lsjedną nazwę pliku w wierszu:

ls -a | cat

Objaśnienie: Polecenie lswykrywa, czy dane wyjściowe są wysyłane do terminala, pliku lub potoku i odpowiednio dostosowuje.

Tak więc, jeśli potokujesz ls -ado Pythona, powinien on działać bez specjalnych środków.

Peter G.
źródło
2
Wow, to jest genialne. Przewaga nad zaakceptowaną odpowiedzią - ta faktycznie działa na powłoce Androida / adb - gdzie lsjest tylko część uproszczonej wersji, więc nie obsługuje-1
mkilmanas
W jaki sposób można uniknąć .i ..„pliki” jest widoczny na wyjściu chociaż?
matanster
@matanster: Zależy, czy w ogóle chcesz zobaczyć pliki kropkowe? Jeśli nie, po prostu upuść opcję -a.
Peter G.
29

Ls jest przeznaczony do spożycia przez ludzi i nie powinieneś analizować jego wydajności .

W skryptach powłoki istnieje kilka przypadków, w których parsowanie danych wyjściowych ls działa, jest najprostszym sposobem na osiągnięcie pożądanego efektu. Ponieważ ls może modyfikować znaki inne niż ASCII i znaki sterujące w nazwach plików, te przypadki są podzbiorem tych, które nie wymagają uzyskania nazwy pliku ls.

W Pythonie nie ma absolutnie żadnego powodu, aby się wywoływać ls. Python ma wszystkie lswbudowane funkcje. Służy os.listdirdo wyświetlania zawartości katalogu i os.statlub osdo uzyskiwania metadanych plików. Inne funkcje w osmodułach mogą być również związane z twoim problemem.


Jeśli uzyskujesz dostęp do zdalnych plików przez ssh, dość dobrym sposobem wyświetlania nazw plików jest sftp:

echo ls -1 | sftp remote-site:dir

Spowoduje to wydrukowanie jednej nazwy pliku w wierszu i, w odróżnieniu od lsnarzędzia, sftpnie zmienia znaków niedrukowalnych. Nadal nie będziesz w stanie rzetelnie wymienić katalogów, w których nazwa pliku zawiera nowy wiersz, ale jest to rzadko wykonywane (pamiętaj o tym jako o potencjalnym problemie bezpieczeństwa, a nie o użyteczności).

W pythonie (uwaga, że ​​metaznaki powłoki muszą być znakami ucieczki remote_dir):

command_line = "echo ls -1 | sftp " + remote_site + ":" + remote_dir
remote_files = os.popen(command_line).read().split("\n")

W przypadku bardziej złożonych interakcji sprawdź tryb wsadowy sftp w dokumentacji.

W niektórych systemach (Linux, Mac OS X, być może w innych unikach, ale na pewno nie w Windows), innym podejściem jest zamontowanie zdalnego systemu plików za pomocą ssh z sshfs , a następnie praca lokalna.

Gilles „SO- przestań być zły”
źródło
Jestem połączony przez SSH ze zdalnym komputerem. Nie znalazłem sposobu na wykonanie funkcji python, takiej jak os.listdir, na zdalnej maszynie w jednym wierszu. Stąd to pytanie. Nie chcę pisać skryptu, aby po prostu wyświetlać listę plików. Czy istnieje jakiś sposób obejścia tego problemu?
fixxxer,
@fixxxer: ssh nie zmienia sytuacji, jest to coś, o czym powinieneś wspomnieć w swoim pierwotnym pytaniu! Myślę, że sftp jest odpowiedni dla twojego przypadku użycia.
Gilles 'SO - przestań być zły'
Przepraszam za zamieszanie. Czy istnieje sposób, w jaki mogę wstawić hasło również w „wierszu polecenia”?
fixxxer,
@ fixxer: Nie wiem, autorzy ssh marszczą brwi w przypadku haseł zapisanych w postaci zwykłego tekstu i zwykle nie ułatwiają tego. Naprawdę powinieneś skonfigurować uwierzytelnianie oparte na kluczach (w sieci jest wiele samouczków i pytania na ten temat na stronie superuser.com ).
Gilles „SO- przestań być zły”
11

możesz użyć ls -1

ls -l wykona również pracę

ILF
źródło
Najlepsza odpowiedź już wymienia dokładnie to, co powiedziałeś. również pytanie wyraźnie mówi, że ls -lnie należy używać.
DevX
2

Łatwe, o ile nazwy plików nie zawierają nowych linii:

find . -maxdepth 1

Jeśli przesyłasz to do innego polecenia, prawdopodobnie powinieneś raczej rozdzielić nazwy plików według bajtów pustych niż znaków nowej linii, ponieważ bajty zerowe nie mogą wystąpić w nazwie pliku (ale znaki nowej linii mogą):

find . -maxdepth 1 -print0

Drukowanie na terminalu będzie prawdopodobnie wyświetlane jako jedna linia, ponieważ puste bajty zwykle nie są drukowane. Niektóre programy mogą potrzebować konkretnej opcji do obsługi danych rozdzielanych znakami zerowymi, takich jak sort's -z. Podobnie twój skrypt musiałby to uwzględnić.

8bittree
źródło