Вывести список файлов с определенными расширениями с помощью ls и grep

153

Я просто хочу получить файлы из текущего каталога и только вывод .mp4 .mp3 .exe файлы, ничего больше. Поэтому я подумал, что могу просто сделать это:

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

Но нет, поскольку первый grep будет выводить только mp4, поэтому остальные 2 grep не будут использоваться.

Любые идеи? PS, запускаю этот скрипт на Slow Leopard.

мятный
источник
1
Это действительно неправильный подход - вместо использования grep, используйте shopt -s nullglobи затем просто обращайтесь к *.exe *.mp3 *.mp4. См. Mywiki.wooledge.org/ParsingLs
Чарльз Даффи
1
Я не могу понять, была ли "Медленный леопард" опечаткой ...
Wowfunhappy
1
@ Wowfunhappy хахаха, определенно была опечатка, я помню, что Snow Leopard был довольно быстр.
Монетный двор

Ответы:

336

Почему нет:

ls *.{mp3,exe,mp4}

Я не уверен, где я узнал это - но я использовал это.

медер омуралиев
источник
1
Это не работает для меня, потому что расширение, которое я использую, предназначено для каталога, поэтому ls перечисляет содержимое каталога.
Ричард Венейбл
1
@RichardVenable добавьте ключ -d, чтобы предотвратить повторное использование каталогов.
Карлос Эухенио Томпсон Пинсон
11
Мне нравится это решение, но оно кажется неудачным, если вам не хватает одного из типов файлов. Например, у вас есть mp3, но нет .exe (Mac OSX, zsh)
JHo
2
Я перенаправил stderr в / dev / null, чтобы избежать, ls: *.exe: No such file or directoryнапример:ls *.{zip,tar.gz,tar} 2>/dev/null
Исаака
1
Когда я запускаю ls foo *. {Tar.gz, zip} прямо в оболочке, это работает, но когда помещаю это в скрипт оболочки, то самое последнее = $ (ls -I ' .done' -tr $ {pkgprefix} . { Tar . gz, zip} | tail -1) Я получил сообщение об ошибке: ls: не может получить доступ к 'bamtools *. {tar.gz, zip}': такого файла или каталога нет, любой умный парень может уточнить ответ.
Кемин Чжоу
41

Используйте регулярные выражения с find:

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

Если вы передаете имена файлов:

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

Это защищает имена файлов, которые содержат пробелы или переводы строк.

OS X findподдерживает только чередование, когда используется -E(расширенная) опция.

find -E . -regex '.*\.(mp3|mp4|exe)'
Приостановлено до дальнейшего уведомления.
источник
2
В Mac OS X:find . -iregex '.*\(mp3\|mp4\|exe\)'
andilabs
3
Энди, это не сработало для меня на Mac OS. Но это сделал: найти -E. -regex '. * (mp3 | mp4 | exe)'
Джозеф Джонсон
Это решение будет загружать файлы, такие как: mysupermp3.jpgрассмотрите возможность добавления $в конце регулярного выражения и \\.расширений перед
Panthro
1
@Panthro: на самом деле, это не так. Find, кажется, использует подразумеваемые якоря. Точка - хорошая идея (нужен только один обратный слеш).
Приостановлено до дальнейшего уведомления.
39

egrep - расширенный grep - поможет здесь

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

должен сделать работу.

чернь
источник
Это оно! Спасибо Только что понял, что я должен делать это без учета регистра, поэтому я использую: ls | egrep -i '\ .mp4 $ | \ .mp3 $ | \ .exe $ Если кто-то еще нуждается в помощи в этот день. Я всегда удивлен скоростью, с которой я получаю свой ответ здесь.
Монетный двор
Я не вижу, как это будет работать. ls без опций производит вывод в столбцах. Привязка к концу строки не будет соответствовать должным образом.
Съемка
4
@camh: lsна терминал (или с -Cопцией) выводит несколько столбцов. lsна трубу (или с -1) имеет один столбец вывода. (Сравните вывод lsс ls | cat).
моб
В конце отсутствует апостроф. В остальном это похоже на работу.
Бьорн
12

самый простой способ - просто использовать ls

ls *.mp4 *.mp3 *.exe
Джошуа К
источник
2
Спасибо, но я уже пробовал это, и мне не нравились ошибки, которые вы получаете, когда нет файла. Ты мог бы исправить это, выполнив: ls * .mp4 * .mp3 * .exe 2> / dev / null Только теперь подумал об этом: P
Mint
1
Я удивлен, что lsне имеет какой-то тихой опции.
MitMaro
2
В bash вы можете сделать «set -o nullglob», и вы не получите ошибок.
кураж
2
Моя ошибка - это должно быть "shopt -s nullglob", а не команда set -o
camh
1
Или просто используйте «echo»: echo * .mp4 * .mp3 * .exe
Адриан Пронк,
9

На всякий случай: почему вы не используете find?

find -iname '*.mp3' -o -iname '*.exe' -o -iname '*.mp4'
П Швед
источник
Вместо этого я обнаружил, что это работает - find . -name '*.mkv' -o -name '*.flv'(добавляя столько предложений -o, сколько требуется). Мне нужно .было указать каталог, а флаг -nameнет -iname- я на macOS 10.13.
Крис
6

Нет необходимости в grep. Подстановочные знаки Shell сделают свое дело.

ls *.mp4 *.mp3 *.exe

Если вы бежали

shopt -s nullglob

тогда непревзойденные глобусы будут удалены полностью и не будут оставлены в командной строке нерасширенными.

Если вы хотите, чтобы регистр не учитывал регистр (поэтому * .mp3 будет соответствовать foo.MP3):

shopt -s nocaseglob
CAMH
источник
Тот же комментарий, который я дал племени Good Time.
Монетный двор
1
Я пытаюсь использовать это с -Rопцией для отображения соответствующих файлов в подкаталогах, но эта опция, похоже, не имеет никакого эффекта, и я все еще получаю только результаты текущего каталога.
Крис
3

Если вы все еще ищете альтернативное решение:

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

Не стесняйтесь добавлять больше флагов -e, если это необходимо.

Хай вю
источник
3

Для пользователей OSX :

Если вы используете ls *.{mp3,exe,mp4}, он выдаст ошибку, если одно из этих расширений не даст результатов.

Использование ls *.(mp3|exe|mp4)вернет все файлы, соответствующие этим расширениям, даже если у одного из расширений было 0 результатов .

james2doyle
источник
5
Я получил синтаксическую ошибку, используя ваш пример ??? 'bash: синтаксическая ошибка рядом с неожиданным токеном `('
нагордон
2
Я думаю, вы имеете в виду ls *.@(mp3|exe|mp4). Вам нужно, shopt -s extglobчтобы это работало. Кстати, lsтоже бесполезно, можно просто сделать printf '%s\n' *.@(mp3|exe|mp4).
gniourf_gniourf
1
Я получаю сообщение о синтаксисе неожиданного токена в macOS 10.13
Chris
1
ls | grep "\.mp4$
\.mp3$
\.exe$"
Джефф Мак
источник
Спасибо, но немного неудобно, используя несколько строк.
Монетный двор
Это + mdfindдает лучший / быстрый поиск когда-либо! mdfind -name querystring | grep "\.h$" находит все заголовки с квест-строкой в ​​заголовке файла. Пронто.
Алекс Грей,
1

ls -R | findstr ".mp3"

ls -R => перечисляет подкаталоги рекурсивно

vardamanpk
источник
-1

Вот один пример, который работал для меня.

find <mainfolder path> -name '*myfiles.java' | xargs -n 1 basename
Джоти Пракаш
источник