Lista plików z określonymi rozszerzeniami z ls i grep

153

Chcę tylko pobrać pliki z bieżącego katalogu i wyprowadzić tylko pliki .mp4 .mp3 .exe nic więcej. Pomyślałem więc, że mogę to zrobić:

ls | grep \.mp4$ | grep \.mp3$ | grep \.exe$

Ale nie, ponieważ pierwszy grep wyświetli tylko pliki mp4, dlatego pozostałe 2 grep nie będą używane.

Jakieś pomysły? PS, uruchamiam ten skrypt w Slow Leopard.

Mennica
źródło
1
To naprawdę niewłaściwe podejście - zamiast używać grep, użyj, shopt -s nullgloba następnie po prostu odwołaj się do *.exe *.mp3 *.mp4. Zobacz mywiki.wooledge.org/ParsingLs
Charles Duffy
1
Nie wiem, czy „Slow Leopard” był literówką ...
Wowfunhappy
1
@Wowfunhappy hahaha, zdecydowanie była to literówka, pamiętam, że myślałem, że Snow Leopard był dość szybki.
Mennica

Odpowiedzi:

336

Dlaczego nie:

ls *.{mp3,exe,mp4}

Nie jestem pewien, gdzie się tego nauczyłem - ale używam tego.

meder omuraliev
źródło
1
To nie działa dla mnie, ponieważ rozszerzenie, którego używam, dotyczy katalogu, więc ls wyświetla zawartość katalogu.
Richard Venable
1
@RichardVenable dodaj przełącznik -d, aby zapobiec powtarzaniu katalogów.
Carlos Eugenio Thompson Pinzón
11
Podoba mi się to rozwiązanie, ale wydaje się, że zawodzi, jeśli brakuje któregokolwiek z typów plików. Na przykład masz mp3, ale nie masz .exe (Mac OSX, zsh)
JHo
2
Przekierowałem stderr do / dev / null, aby uniknąć ls: *.exe: No such file or directorynp:ls *.{zip,tar.gz,tar} 2>/dev/null
Isaac
1
Kiedy uruchamiam ls foo *. {Tar.gz, zip} bezpośrednio w powłoce, to działa, ale po umieszczeniu tego w skrypcie powłoki last = $ (ls -I ' .done' -tr $ {pkgprefix} . {Tar. gz, zip} | tail -1) Otrzymałem komunikat o błędzie: ls: nie można uzyskać dostępu do 'bamtools *. {tar.gz, zip}': Nie ma takiego pliku lub katalogu, każdy mądrzejszy facet może udoskonalić odpowiedź.
Kemin Zhou
41

Używaj wyrażeń regularnych z find:

find . -iregex '.*\.\(mp3\|mp4\|exe\)' -printf '%f\n'

Jeśli piszesz nazwy plików:

find . -iregex '.*\.\(mp3\|mp4\|exe\)' -printf '%f\0' | xargs -0 dosomething

Chroni to nazwy plików, które zawierają spacje lub znaki nowej linii.

OS X findobsługuje naprzemienność tylko wtedy, gdy -Eużywana jest opcja (ulepszona).

find -E . -regex '.*\.(mp3|mp4|exe)'
Wstrzymano do odwołania.
źródło
2
W systemie Mac OS X:find . -iregex '.*\(mp3\|mp4\|exe\)'
andilabs
3
andi, to nie działa dla mnie na Mac OS. Ale to zrobiło: znajdź -E. -regex '. * (mp3 | mp4 | exe)'
Joseph Johnson
To rozwiązanie załaduje pliki takie jak: mysupermp3.jpgrozważ dodanie $na końcu wyrażenia regularnego i \\.przed rozszerzeniami
Panthro
1
@Panthro: właściwie to nie będzie. Wydaje się, że Find używa domniemanych kotwic. Kropka to dobry pomysł (potrzebny jest tylko jeden lewy ukośnik).
Wstrzymano do odwołania.
39

egrep - rozszerzona grep - pomoże tutaj

ls | egrep '\.mp4$|\.mp3$|\.exe$'

powinien wykonać pracę.

tłum
źródło
Otóż ​​to! Dzięki Właśnie zdałem sobie sprawę, że powinienem nie rozróżniać wielkości liter, więc używam: ls | egrep -i '\ .mp4 $ | \ .mp3 $ | \ .exe $ Gdyby ktoś inny potrzebował pomocy w tym dniu. Zawsze jestem zaskoczony szybkością, z jaką otrzymuję tutaj odpowiedź.
Mint
Nie wiem, jak to by zadziałało. ls bez żadnych opcji daje wynik w kolumnach. Zakotwiczenie do końca linii nie będzie pasować prawidłowo.
camh
4
@camh: lsdo terminala (lub z -Copcją) generuje wielokolumnowe wyjście. lsdo potoku (lub z -1) ma pojedynczą kolumnę. (Porównaj dane wyjściowe z lsz ls | cat).
mob
Na końcu brakuje apostrofu. Poza tym wydaje się działać.
Björn
12

najłatwiej jest po prostu użyć ls

ls *.mp4 *.mp3 *.exe
Joshua K.
źródło
2
Dzięki, ale już to próbowałem i nie podobały mi się błędy, które otrzymujesz, gdy nie ma pliku. Mogłem to naprawić, wykonując: ls * .mp4 * .mp3 * .exe 2> / dev / null Tylko o tym pomyślałem: P
Mint
1
Dziwię się, że lsnie ma cichej opcji.
MitMaro
2
W bashu możesz zrobić "set -o nullglob" i nie otrzymasz błędów.
camh
2
Mój błąd - to powinno być „shopt -s nullglob”, a nie polecenie set -o
camh
1
Lub po prostu użyj „echo”: echo * .mp4 * .mp3 * .exe
Adrian Pronk
9

Na wszelki wypadek: dlaczego nie używasz find?

find -iname '*.mp3' -o -iname '*.exe' -o -iname '*.mp4'
P Shved
źródło
Okazało się, że to zadziałało - find . -name '*.mkv' -o -name '*.flv'(dodając tyle klauzul -o, ile potrzeba). Potrzebowałem .do wskazania katalogu i flagi -namenie -iname- jestem na macOS 10.13.
Chris
6

Nie ma potrzeby używania grepa. Dzikie karty powłoki załatwią sprawę.

ls *.mp4 *.mp3 *.exe

Jeśli uciekłeś

shopt -s nullglob

wtedy niedopasowane globy zostaną całkowicie usunięte i nie pozostaną nierozwinięte w wierszu poleceń.

Jeśli chcesz, aby globbing nie uwzględniał wielkości liter (więc * .mp3 będzie pasować do foo.MP3):

shopt -s nocaseglob
camh
źródło
Ten sam komentarz, który przekazałem Good Time Tribe.
Mint
1
Próbuję użyć tego z -Ropcją wyświetlania pasujących plików w podkatalogach, ale ta opcja nie wydaje się mieć żadnego efektu i nadal otrzymuję tylko wyniki bieżącego katalogu.
Chris
3

Jeśli nadal szukasz alternatywnego rozwiązania:

ls | grep -i -e '\\.tcl$' -e '\\.exe$' -e '\\.mp4$'

W razie potrzeby możesz dodać więcej flag -e.

Hai Vu
źródło
3

Dla użytkowników OSX :

Jeśli użyjesz ls *.{mp3,exe,mp4}, wyświetli błąd, jeśli jedno z tych rozszerzeń nie da żadnych wyników.

Użycie ls *.(mp3|exe|mp4)zwróci wszystkie pliki pasujące do tych rozszerzeń, nawet jeśli jedno z rozszerzeń dało 0 wyników .

james2doyle
źródło
5
Wystąpił błąd składni na Twoim przykładzie ??? 'bash: błąd składni w pobliżu nieoczekiwanego tokenu' ('
nagordon
2
Chyba masz na myśli ls *.@(mp3|exe|mp4). Potrzebujesz, shopt -s extglobżeby to zadziałało. Nawiasem mówiąc, lsjest też bezużyteczny, możesz po prostu zrobić printf '%s\n' *.@(mp3|exe|mp4).
gniourf_gniourf
1
Otrzymuję nieoczekiwany komunikat o składni w systemie macOS 10.13
Chris,
1
ls | grep "\.mp4$
\.mp3$
\.exe$"
Jeff Mc
źródło
Dzięki, ale trochę niewygodne używanie kilku linii.
Mint
Daje to + mdfindnajlepsze / najszybsze wyszukiwania! mdfind -name querystring | grep "\.h$" znajduje wszystkie nagłówki z quesrystring w tytule pliku. pronto.
Alex Grey
1

ls -R | findstr ".mp3"

ls -R => rekurencyjnie wyświetla podkatalogi

vardamanpk
źródło
-1

Oto jeden przykład, który zadziałał dla mnie.

find <mainfolder path> -name '*myfiles.java' | xargs -n 1 basename
Jyoti Prakash
źródło