команда linux find для имен файлов без расширения для неизвестных расширений

команда linux find для имен файлов без расширения для неизвестных расширений

Мне нравится использовать следующую команду для печати имен файлов, но она печатает их с расширениями.

find . -type f -printf '%f\n'

В моем каталоге много файлов с разными расширениями. Я пробовал добавлять --ignore='*.*'и до, и после -printf, но это не сработало. пример; у меня есть файлы myfile1.txt, myfile2.mp3 и т. д. Мне нужно, чтобы он печатал myfile1, myfile2 и т. д. Как мне это сделать?

решение1

Если я правильно вас понял (Я не видел, см. вторую часть ответа.), следует избегать перечисления имен файлов, содержащих символ точки.

Это позволит сделать следующее:

find . -type f ! -name '*.*'

Шаблон подстановки имени файла *.*будет соответствовать любому имени файла, содержащему хотя бы одну точку. Предыдущее !отрицает смысл соответствия, что означает, что имена путей, которые дойдут до конца, будут теми, которые не содержат точек в своих именах. Вдействительно древнийshells, вы можете захотеть экранировать !as \!(или обновить вашу установку Unix). Одинокий !не будет вызыватьbashИстория расширения возможностей.

Чтобы напечатать только компонент имени файла из найденного пути, с помощью GNU find:

find . -type f ! -name '*.*' -printf '%f\n'

Со стандартом find(или GNU, findесли на то пошло):

find . -type f ! -name '*.*' -exec basename {} \;

Перед использованием этого в подстановке команд в цикле см. "Почему циклический просмотр вывода find является плохой практикой?".


Чтобы вывести список всех имен файлов и одновременно удалить все после последней точки в имени («удалить расширение»), можно использовать

find . -type f -exec sh -c '
    for pathname do
        pathname=$( basename "$pathname" )
        printf "%s\n" "${pathname%.*}"
    done' sh {} +

Это отправит все найденные пути всех файлов в короткий цикл оболочки. Цикл возьмет каждый путь и вызовет basenameего для извлечения компонента имени файла из пути, а затем выведет результирующую строку со всем, что находится после последней удаленной точки.

Расширение параметра ${pathname%.*}означает «удалить самую короткую строку, совпадающую с .*(точка, за которой следует произвольный текст) из конца значения $pathname». Это имело бы эффект удаления суффикса имени файла после последней точки в имени файла.

Для получения дополнительной информации find ... -exec ... {} +см., например, "Понимание опции -exec команды `find`".

решение2

В Linux нет такого понятия, как расширение файла. Буква «А» .в имени файла не имеет никакого значения (несмотря на то, что «а» .какпервыйсимвол в имени файла идентифицирует его как скрытый файл).

Кроме того, проверка страницы руководства по findмоей системе не выявила никаких --ignoreопций.

Тем не менее, если вы хотите игнорировать файлы, .в имени которых есть символ , вы можете использовать findоператор -not:

find -type f -not -name '*.*' -print

решение3

Как уже отмечалось, "расширения" на самом деле ничего не значат для систем Unix. Но мы можем удалить их из списка с помощью простой sedкоманды.

например

find * -type f -print | sed 's/\.[^.]*$//'

Если есть каталоги и вы не хотите, чтобы они отображались в списке, то

find * -type f -printf "%f\n" | sed 's/\.[^.]*$//'

Для одного каталога мы можем просто использовать lsвместоfind

ls | sed 's/\.[^.]*$//'

решение4

пытаться

find . -type f \! -name '*.*' -print

где

  • \!: не (! необходимо экранировать)
  • name '*.*': имя файла с расширением

Связанный контент