Jak wyprowadzać tylko nazwy plików (ze spacjami) w ls -Al?


78

Powinienem powtarzać tylko nazwy plików lub katalogów o tej konstrukcji:

ls -Al | while read string
do
...
done

ls -Al wynik :

drwxr-xr-x  12 s162103  studs         12 march 28 12:49 personal domain
drwxr-xr-x   2 s162103  studs          3 march 28 22:32 public_html
drwxr-xr-x   7 s162103  studs          8 march 28 13:59 WebApplication1

Na przykład, jeśli spróbuję:

ls -Al | while read string
do
echo "$string" | awk '{print $9}
done

następnie wypisuj tylko pliki i katalogi bez spacji. Jeśli plik lub katalog ma spacje takie jak „domena osobista”, będzie to tylko słowo „osobisty”.

Potrzebuję bardzo prostego rozwiązania. Może jest lepsze rozwiązanie niż awk.


2
Dlaczego nie tylko ls -Al *' '*? Wynik parsowania lsnigdy nie prowadzi do niczego dobrego.
manatwork

1
Jeśli potrzebujesz czegoś, co zadziała w dowolnym * nix, unikaj używania ls -Al | while. Prostym i bardziej niezawodnym sposobem jest for string in *; do echo "$string"; done.
forcefsck

Potrzebuję tylko z tą konstrukcją. OK, nie proste, każde rozwiązanie!
Alex Zern

1
Dlaczego potrzebne ls ? Analiza lsi „działa w całości * nix i nie zepsuje się, jeśli coś się stanie”, nie idą dobrze razem.
terdon

Odpowiedzi:


97

Ty naprawdę nie powinien analizować dane wyjściowels . Jeśli jest to zadanie domowe i wymaga tego Twój profesor, nie wie o czym mówi. Dlaczego nie zrobisz czegoś takiego:

Dobry ...

find ./  -printf "%f\n"

lub

for n in *; do printf '%s\n' "$n"; done

...Źli...

Jeśli naprawdę chcesz używać ls, możesz uczynić go trochę bardziej niezawodnym, wykonując coś takiego:

ls -lA | awk -F':[0-9]* ' '/:/{print $2}'

... i brzydkie

Jeśli nalegasz , aby zrobić to w niewłaściwy, niebezpieczny sposób i po prostu musisz użyć whilepętli, wykonaj następujące czynności:

ls -Al | while IFS= read -r string; do echo "$string" | 
    awk -F':[0-9]* ' '/:/{print $2}'; done

Poważnie, ale nie rób tego.


drwx------ 2 s162103 studs 3 oct. 9 2012 .ssh drwxr-xr-x 3 s162103 studs 6 oct. 25 09:02 .subversion drwxrwxrwt 3 s162103 studs 3 nov. 15 2012 .TempoItemsczasami mam randkę bez czasu, tylko rok i
gapię się

1
@AlexZern Cóż, to jeden z powodów, dla których nie analizujesz wyników ls.
terdon

2
@AlexZern, po co ci ten -lprzełącznik? Jeśli wszystko czego potrzebujesz to nazwy plików, po prostu uruchom ls -A. Używanie -ltylko utrudnia życie, ponieważ teraz trzeba przeanalizować wyniki.
terdon

ponieważ potrzebuję dodatkowych informacji, takich jak dostęp, data, właściciel itp. Napisałem ogromny skrypt, który działa dobrze, z wyjątkiem nazw plików do drukowania i katalogów ze spacjami.
Alex Zern

3
OK. Mamy tutaj problem XY . lsto po prostu nie najlepszy sposób na uzyskanie tego, czego potrzebujesz. Dlaczego nie opublikujesz nowego pytania wyjaśniającego informacje, które chcesz zebrać, a my możemy zasugerować, jak to zrobić. Alternatywnie możesz użyć skryptu w obecnej postaci i skorzystać z jednej z powyższych sugestii, aby wydrukować tylko nazwę. Ale poważnie, nie analizuj ls, po prostu powiedz nam dokładnie, co próbujesz zrobić w nowym pytaniu.
terdon

74

Czy jest jakiś powód, dla którego ls -A1* nie działa?

Na przykład:

$ touch file1 file2 file\ with\ spaces
$ ls -Al
total 0
-rw-r--r-- 1 bahamat bahamat 0 Mar 30 22:31 file1
-rw-r--r-- 1 bahamat bahamat 0 Mar 30 22:31 file2
-rw-r--r-- 1 bahamat bahamat 0 Mar 30 22:31 file with spaces
$ ls -A1
file1
file2
file with spaces
$

* Uwaga: to wielka litera A i numer jeden.


4
-1 jest genialny. Nie wiedziałem, że jest dostępny. (Wiem, wiem, RTFM.)
The Lazy Coder

który działa tylko w bieżącym katalogu, jeśli chcesz wyświetlić listę nazw plików z innego katalogu, powiedz ~ / projects, wtedy otrzymasz pełne ścieżki zamiast nazw plików
thecotne

@ thecotne na Mac 10.9.5 wyświetla tylko nazwy plików. Z jakiego systemu operacyjnego korzystasz?
AJP,

uruchamiam to ls ~ / projects / *. sublime-project -A1 for ls ~ / projects -A1 dostaję tylko nazwy
thecotne

3
@ TheLazyCoder nie powinien czytać instrukcji.
c24w

41

Zastanawiam się, dlaczego nikt nie wspomniał o tym prostym poleceniu:

ls -a | sort

2
Znakomity! Masz pojęcie, w jaki sposób sortpotokowanie powoduje, że blok wielokolumnowy jest niepodzielny na jedną kolumnę?
msciwoj

@msciwoj po prostu bierze ciągi znaków oddzielone białymi spacjami i drukuje je posortowane oddzielone liniami końcowymi
Ben

DOSKONAŁY! Dlaczego nie został on oznaczony jako prawdziwa odpowiedź !?
夏 期 劇場

3
Działa tutaj, ponieważ lspowraca do ls -1(wyjście z pojedynczą kolumną), gdy jego wyjście nie trafia do terminala (i wyłącza cytowanie / zamianę niedrukowalnych znaków; @Kusalananda, jeśli lsnie jest zgodne z POSIX, jeśli nadal tak jest). lsdane wyjściowe są już posortowane. Więc potokowanie go do sortco najwyżej nic nie zrobi, a co gorsza zniekształci dane wyjściowe (jeśli nazwy plików zawierają znaki nowego wiersza) lub zawiedzie dla nazw plików, które nie są tekstem. ls -a | catbyłoby lepiej. Lub nawet lepiej, ls -A1jak już wspomniano (i ponieważ generalnie chcesz
zamieniać

1
@ StéphaneChazelas Noted. lszachowuje się inaczej, gdy wyjście nie jest terminalem.
Kusalananda

3

Nie można przeanalizować wyniku ls, nie mówiąc już o tym, ls -lponieważ znak nowej linii, podobnie jak spacja, jest tak samo poprawnym znakiem, jak każdy znak w nazwie pliku. Musisz także wziąć pod uwagę dowiązania symboliczne, które mają dane wyjściowe podobne ... foo -> bar.

Dlaczego miałbyś użyć -lmimo wszystko, jeśli chcesz tylko nazwę pliku?

Po prostu zrób:

for file in *; do
  ...
done

Jeśli chcesz dołączyć pliki kropek (oprócz .i ..), w zależności od powłoki:

zsh:

for file in *(ND); do
  ...
done

bash:

shopt -s nullglob dotglob
for file in *; do
  ...
done

ksh93:

FIGNORE='@(.|..)'
for file in ~(N)*; do
  ...
done

POSIXly:

for file in .[!.]* ..?* *; do
  [ -e "$file" ] || [ -L "$file" ] || continue
  ...
done


1
ls -Al | tr -s ' ' | cut -f9- -d' '

skompresuj wiele spacji do pojedynczych spacji za pomocą tr, a następnie możesz użyć wycięcia do podziału na polach




Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.