Bash: ls * bez grupowania folderów


12

Jeśli napiszę:

ls source/*

source/fonts:
fontello

source/images:
bg1.png                eng.png        fra.png   

Otrzymuję listę plików, pogrupowanych według nazw folderów. Jak mogę po prostu uzyskać listę nazw plików?

ls source/*

source/fonts/fontello
source/images/bg1.png
source/images/eng.png
source/images/fra.png   

Dzięki


Jeśli jest to do użytku skryptowego, możesz zobaczyć mywiki.wooledge.org/ParsingLs . (To powiedziawszy, istnieją również sposoby findniewłaściwego użycia ; szczególnie, jeśli biegniesz for file in $(find ...), trafiłeś jeden z nich).
Charles Duffy,

Odpowiedzi:


13

Nie wydaje się to możliwe bez zmiany wydajności, ale tutaj jest prosty alternatywny sposób:

find source/ -type f

Lub (specyficzne dla GNU find), aby uzyskać tylko głębokie pliki w pytaniu:

find source/ -type f -mindepth 2 -maxdepth 2

(lub jeśli chcesz katalogów takich jak lsdaje, usuń -type f)


5

Możesz po prostu trzymać się ls, jeśli dodasz psychedlics ( ls -d):

# mkdir test
# cd test
# mkdir A B C
# touch {A,B,C}/file*
# ls -d */*    
A/file  B/file  C/file

@Cthulhu ok mój przykład jest za krótki, jeśli masz foldery w A, B a / o C, -d pomaga wyświetlić tylko to, co wybrałeś. Właściwie to nie lubię znaleźć i możesz zdefiniować głębokość za pomocą argumentu ls -d
ikrabbe

Zasugerowałem edycję drugiej odpowiedzi, aby ograniczyć głębokość.
o11c

@ o11c bardzo dobry, ale wciąż findjest grubą bestią.
ikrabbe

3

Możesz być zainteresowany „biedakiem find”:

shopt -s globstar

shopt -s s ETS nazwany opcję powłoki (y). globstarRozwiązaniem jest zdefiniowany w następujący sposób bash (1) :

Jeśli jest ustawiony, wzorzec **użyty w kontekście rozszerzenia nazwy pliku / ścieżki będzie pasował do plików [sic] i zero lub więcej katalogów i podkatalogów. Jeśli po wzorcu występuje a /, tylko katalogi i podkatalogi są zgodne.

Po zakończeniu możesz wykonać shopt -s globstardowolne z następujących poleceń:

ls -d1 - source / **                  # Znak po „d” jest cyfrą. 
ls -d - źródło / ** | cat             # tzn. zapisze to w potoku do dowolnego polecenia. 
printf "% s \ n" źródło / **

wytworzy wynik:

source/
source/fonts
source/fonts/fontello
source/images
source/images/bg1.png
source/images/eng.png
source/images/fra.png

Niestety dotyczy to również nazw katalogów. To może pomóc trochę wiedzieć, że

printf "%s\n" source/**/

wytworzy wynik:

source/
source/fonts
source/images

tj. tylko nazwy katalogów. Możesz przekierować wyjście jednej z pierwszego zestawu poleceń do jednego pliku, przekierować wyjście powyżej drugiego pliku, a następnie użyć comm, difflub coś podobnego, aby odjąć drugi plik z pierwszego, pozostawiając tylko zwykły pliki (inne niż katalogi). Ale nie rób tego.

Innym podejściem (to niewiele lepsze) jest

ls -d --file-type -- source/** | grep -v '/$'

Ta --file-typeopcja lswyświetla / na końcu nazwy każdego katalogu (i inne znaki na końcu innych (specjalnych) typów plików), na przykład:

source //                             # Dodano dodatkowy jeden 
source / fonts /                        # Dodano jeden
źródło / fonts / fontello
źródło / obrazy /                       # Dodano jeden
source / images / bg1.png
source / images / eng.png
source / images / fra.png

a następnie grep -v '/$'usuwa linie, które kończą się /; tzn. nazwy katalogów. Niestety --file-typeopcja nie jest określona przez POSIX . Jeśli twoja wersja lsgo nie obsługuje, użyj -F. To tak, jakby --file-type wyświetlał również *na końcach nazw plików wykonywalnych, co dla niektórych osób jest denerwujące. Możesz je wyeliminować za pomocą sed:

ls -dF -- source/** | sed -e '/\/$/d' -e 's/\*$//'

Jeśli chcesz coś zrobić ze wszystkimi plikami (i tylko plikami), możesz to zrobić

dla f w źródle / **
robić
    jeśli [-f "$ f"]
    następnie
        W tym miejscu wstaw polecenia do zwykłych plików.
    fi
gotowy

Uwagi:

  • Kiedy lsjest wyprowadzanie na terminal, a to nie jest w -l( l trybie Ong), zapisuje wiele nazw na linię (chyba, że nazwy są bardzo długie). Możesz zmusić go do napisania jednej nazwy w wierszu, określając -1(jedną) lub przekierowując dane wyjściowe do pliku lub potoku.
  • Prawdopodobnie nie naprawdę potrzebne --w lspoleceniach ponieważ jesteś wymieniając katalogu, którego zawartość została utworzona. Powinieneś go używać podczas wpisywania *do nieznanego katalogu, jako ochronę przed nazwami plików zaczynającymi się od -.
  • Nie próbuj analizować danych wyjściowych ls.
  • Opcja globstarpowłoki wydaje się nie być zdefiniowana przez POSIX. (W rzeczywistości nie jestem pewien, czy POSIX rozpoznaje jakiekolwiek opcje powłoki.) Chociaż wydaje się, że jest to bashism, uważaj - może nie być obecny we wszystkich wersjach bash.
  • Jeśli fontslub imagesma podkatalogi, **wyświetli je wszystkie, rekurencyjnie, aż do końca. Jednym (nieco niechlujnym i zawodnym) sposobem ograniczenia głębokości jest

    ls -d --file-type -- source/** | grep -v '\(/.*\)\{3\}'
    

    który usuwa wiersze zawierające trzy lub więcej /znaków.

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.