Использование 'find' для возврата имен файлов без расширения

Использование 'find' для возврата имен файлов без расширения

31.01.2017 09:58:30 Просмотров 43 Источник

У меня есть каталог (с подкаталогами), в котором я хочу найти все файлы, которые имеют ".расширение "ipynb". Но я хочу, чтобы команда "найти" просто вернула мне эти имена файлов без расширения.

Я знаю первую часть.:

find . -type f -iname "*.ipynb" -print    

Но как мне тогда получить имена без расширения "ipynb"? Любые ответы очень ценятся...

У вопроса есть решение - Посмотреть?

Ответы - Использование 'find' для возврата имен файлов без расширения / Using 'find' to return filenames without extension

Является ответом!
kenorb

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 ';'
https://stackoverflow.com/questions/41965415/using-find-to-return-filenames-without-extension/41965460#comment71126501_41965460
Применяя basename будет также выбрасывать каталога компонентов.
https://stackoverflow.com/questions/41965415/using-find-to-return-filenames-without-extension/41965460#comment71131566_41965460
Я считаю, что это то, что требуется, список только имена файлов без расширения.
https://stackoverflow.com/questions/41965415/using-find-to-return-filenames-without-extension/41965460#comment77844258_41965460
Выполнение basenameодин раз на файл кажется довольно неэффективным. find . -name '*.ipynb' -exec bash -c 'printf "%s\n" "${@%.*}"' _ {} +просто вызовет одну оболочку на пакет файлов, что значительно меньше накладных расходов.
https://stackoverflow.com/questions/41965415/using-find-to-return-filenames-without-extension/41965460#comment77844545_41965460
@CharlesDuffy добавлен в список. Не будет ли вызов bash для каждого файла также неэффективным? Или он выполняется на всех файлах из-за +?
https://stackoverflow.com/questions/41965415/using-find-to-return-filenames-without-extension/41965460#comment77845222_41965460
@kenorb, +означает, что мы передаем несколько файлов в каждый экземпляр bash - если весь список помещается в одну командную строку, мы вызываем bash только один раз.
https://stackoverflow.com/questions/41965415/using-find-to-return-filenames-without-extension/41965460#comment98247572_41965460
@CharlesDuffy что произойдет, если весь список не поместится в одну команду?
https://stackoverflow.com/questions/41965415/using-find-to-return-filenames-without-extension/41965460#comment98264447_41965460
@IMTheNachoMan, ...в таком случае, -exec ... {} +выполняет команду несколько раз (каждый с подмножеством списка файлов), так же, как это делает xargs.
V. Michel

31.01.2017 10:46:28

Если вам нужно иметь имя с каталогом, но без расширения :

find .  -type f -iname "*.ipynb" -exec sh -c 'f=$(basename $1 .ipynb);d=$(dirname $1);echo "$d/$f"' sh {} \;
eewanco

31.01.2017 10:52:20

Вот простое решение:

find . -type f -iname "*.ipynb" | sed 's/\.ipynb$//1'
https://stackoverflow.com/questions/41965415/using-find-to-return-filenames-without-extension/41966340#comment85472208_41966340
Нет необходимости в /1, так как шаблон не может совпадать более одного раза (при условии отсутствия встроенных новых строк в именах файлов).
https://stackoverflow.com/questions/41965415/using-find-to-return-filenames-without-extension/41966340#comment100428645_41966340
Я использовал этот, так как он не развивает процесс, такой как bash или basename для каждого файла. Немного нестандартно, но быстрее.
user1934428

01.02.2017 10:46:38

find . -type f -iname "*.ipynb" | grep -oP '.*(?=[.])'

Флаг-o выводит только согласованную часть. Флаг-P соответствует регулярным выражениям Perl. Это необходимо, чтобы сделать lookahead (?=[.])работа.

Shakiba Moshiri

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

niglesias

01.08.2017 06:44:49

Если этого не произойдет".ipynb " строка на любое имя файла, кроме суффикса, то вы можете попробовать этот более простой способ, используя tr:

find . -type f -iname "*.ipynb" -print | tr -d ".ipbyn"
Diego

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
bentocin

25.01.2020 08:30:01

Еще один простой способ, который использует basename:

find . -type f -iname '*.ipynb' -exec basename -s '.ipynb' {} +

Использование +уменьшит количество вызовов команды (manpage):

- команда exec {} +

Этот вариант действия-exec запускает указанную команду на выбранные файлы, но командная строка строится путем добавления каждое выбранное имя файла в конце; общее число вызовов команды будет намного меньше, чем количество совпадающих файлов. Командная строка построена примерно так же способ, которым xargs строит свои командные строки. Только один экземпляр '{} 'допускается в пределах команды, и (когда find находится вызывается из оболочки) он должен быть заключен в кавычки (например,' {}') чтобы защитить его от интерпретации снарядами. Команда есть выполняется в стартовом каталоге. Если любой вызов с форма " + " возвращает ненулевое значение в качестве состояния выхода, затем find возвращает ненулевое состояние выхода. Если найти встречает ошибка, это иногда может привести к немедленному выходу, так что некоторые отложенные команды могут вообще не выполняться. По этой причине-exec моя команда ... {} + - выход может не привести к моей команде на самом деле бегут. Этот вариант остается всегда возвращается истинный.

Using-swith basenameruns принимает несколько имен файлов и удаляет указанный суффикс (manpage):

-множество

поддерживайте несколько аргументов и относитесь к каждому из них как к имени

-s, -- suffix=суффикс

удалить завершающий суффикс; подразумевает -a

Закрыть X