Использование 'find' для возврата имен файлов без расширения
У меня есть каталог (с подкаталогами), в котором я хочу найти все файлы, которые имеют ".расширение "ipynb". Но я хочу, чтобы команда "найти" просто вернула мне эти имена файлов без расширения.
Я знаю первую часть.:
find . -type f -iname "*.ipynb" -print
Но как мне тогда получить имена без расширения "ipynb"? Любые ответы очень ценятся...
Ответы - Использование 'find' для возврата имен файлов без расширения / Using 'find' to return filenames without extension

31.01.2017 10:01:26
Чтобы вернуть только имена файлов без расширения, попробуйте:
find . -name "*.ipynb" -execdir sh -c 'printf "%s\n" "${0%.*}"' {} ';'
или:
find "$PWD" -type f -iname "*.ipynb" -execdir basename {} .ipynb ';'
или:
find . -type f -iname "*.ipynb" -exec basename {} .ipynb ';'
однако вызов basename
для каждого файла может быть неэффективным, поэтому предложение @CharlesDuffy:
find . -name '*.ipynb' -exec bash -c 'printf "%s\n" "${@%.*}"' _ {} +
или:
find . -iname '*.ipynb' -execdir basename -s '.sh' {} +
Использование +
означает, что мы передаем несколько файлов в каждый экземпляр bash, поэтому, если весь список помещается в одну командную строку, мы вызываем bash только один раз.
Чтобы напечатать полный путь и имя файла (без расширения) в одной строке, попробуйте:
find . -name "*.ipynb" -exec sh -c 'printf "%s\n" "${0%.*}"' {} ';'
или:
find "$PWD" -type f -iname "*.ipynb" -print | grep -o "[^\.]\+"
Чтобы напечатать полный путь и имя файла в отдельных строках:
find "$PWD" -type f -iname "*.ipynb" -exec dirname "{}" ';' -exec basename "{}" .ipynb ';'

basename
будет также выбрасывать каталога компонентов.


basename
один раз на файл кажется довольно неэффективным. find . -name '*.ipynb' -exec bash -c 'printf "%s\n" "${@%.*}"' _ {} +
просто вызовет одну оболочку на пакет файлов, что значительно меньше накладных расходов.

+
?

+
означает, что мы передаем несколько файлов в каждый экземпляр bash - если весь список помещается в одну командную строку, мы вызываем bash только один раз.


-exec ... {} +
выполняет команду несколько раз (каждый с подмножеством списка файлов), так же, как
это делает xargs.



/1
, так как шаблон не может совпадать более одного раза (при условии отсутствия встроенных новых строк в именах файлов).


01.02.2017 10:46:38
find . -type f -iname "*.ipynb" | grep -oP '.*(?=[.])'
Флаг-o выводит только согласованную часть. Флаг-P соответствует регулярным выражениям Perl. Это необходимо, чтобы сделать lookahead (?=[.])
работа.

01.02.2017 12:10:16
Perl Один Лайнер
чего ты хочешь?
find . | perl -a -F/ -lne 'print $F[-1] if /.*.ipynb/g'
Тогда не ваш код
чего вы не хотите
find . | perl -a -F/ -lne 'print $F[-1] if !/.*.ipynb/g'
ЗАПИСКА
В Perl нужно ставить дополнительно .
. Так что ваш шаблон будет .*.ipynb


12.03.2018 02:39:09
Если вы не знаете, что расширение есть или их несколько, вы можете использовать это:
find . -type f -exec basename {} \;|perl -pe 's/(.*)\..*$/$1/;s{^.*/}{}'
и для списка файлов без дубликатов (изначально отличающихся по пути или расширению)
find . -type f -exec basename {} \;|perl -pe 's/(.*)\..*$/$1/;s{^.*/}{}'|sort|uniq

25.01.2020 08:30:01
Еще один простой способ, который использует basename
:
find . -type f -iname '*.ipynb' -exec basename -s '.ipynb' {} +
Использование +
уменьшит количество вызовов команды (manpage):
- команда exec {} +
Этот вариант действия-exec запускает указанную команду на выбранные файлы, но командная строка строится путем добавления каждое выбранное имя файла в конце; общее число вызовов команды будет намного меньше, чем количество совпадающих файлов. Командная строка построена примерно так же способ, которым xargs строит свои командные строки. Только один экземпляр '{} 'допускается в пределах команды, и (когда find находится вызывается из оболочки) он должен быть заключен в кавычки (например,' {}') чтобы защитить его от интерпретации снарядами. Команда есть выполняется в стартовом каталоге. Если любой вызов с форма " + " возвращает ненулевое значение в качестве состояния выхода, затем find возвращает ненулевое состояние выхода. Если найти встречает ошибка, это иногда может привести к немедленному выходу, так что некоторые отложенные команды могут вообще не выполняться. По этой причине-exec моя команда ... {} + - выход может не привести к моей команде на самом деле бегут. Этот вариант остается всегда возвращается истинный.
Using-s
with basename
runs принимает несколько имен файлов и удаляет указанный суффикс (manpage):
-множество
поддерживайте несколько аргументов и относитесь к каждому из них как к имени
-s, -- suffix=суффикс
удалить завершающий суффикс; подразумевает -a