
Мне нравится использовать следующую команду для печати имен файлов, но она печатает их с расширениями.
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 '*.*'
: имя файла с расширением