Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using 'find' to return filenames without extension

I have a directory (with subdirectories), of which I want to find all files that have a ".ipynb" extension. But I want the 'find' command to just return me these filenames without the extension.

I know the first part:

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

But how do I then get the names without the "ipynb" extension? Any replies greatly appreciated...

like image 770
Siavosh Mahboubian Avatar asked Jan 31 '17 18:01

Siavosh Mahboubian


People also ask

How do you find the file name without an extension?

GetFileNameWithoutExtension(ReadOnlySpan<Char>) Returns the file name without the extension of a file path that is represented by a read-only character span.

How do I find a specific filename?

For example, if you want to search only file names and not file contents, tap or click Other properties, choose Name, and then enter your search term. If you can't find what you're looking for in a specific library or folder, you can expand the search to include different locations.

How do I remove a filename extension in bash?

Remove File Extension Using the basename Command in Bash If you know the name of the extension, then you can use the basename command to remove the extension from the filename. The first command-Line argument of the basename command is the variable's name, and the extension name is the second argument.


4 Answers

To return only filenames without the extension, try:

find . -type f -iname "*.ipynb" -execdir sh -c 'printf "%s\n" "${0%.*}"' {} ';'

or (omitting -type f from now on):

find "$PWD" -iname "*.ipynb" -execdir basename {} .ipynb ';'

or:

find . -iname "*.ipynb" -exec basename {} .ipynb ';'

or:

find . -iname "*.ipynb" | sed "s/.*\///; s/\.ipynb//"

however invoking basename on each file can be inefficient, so @CharlesDuffy suggestion is:

find . -iname '*.ipynb' -exec bash -c 'printf "%s\n" "${@%.*}"' _ {} +

or:

find . -iname '*.ipynb' -execdir basename -s '.sh' {} +

Using + means that we're passing multiple files to each bash instance, so if the whole list fits into a single command line, we call bash only once.


To print full path and filename (without extension) in the same line, try:

find . -iname "*.ipynb" -exec sh -c 'printf "%s\n" "${0%.*}"' {} ';'

or:

find "$PWD" -iname "*.ipynb" -print | grep -o "[^\.]\+"

To print full path and filename on separate lines:

find "$PWD" -iname "*.ipynb" -exec dirname "{}" ';' -exec basename "{}" .ipynb ';'
like image 86
kenorb Avatar answered Oct 07 '22 02:10

kenorb


Here's a simple solution:

find . -type f -iname "*.ipynb" | sed 's/\.ipynb$//1'
like image 39
Vercingatorix Avatar answered Oct 07 '22 01:10

Vercingatorix


I found this in a bash oneliner that simplifies the process without using find

for n in *.ipynb; do echo "${n%.ipynb}"; done
like image 5
jjisnow Avatar answered Oct 07 '22 03:10

jjisnow


If you need to have the name with directory but without the extension :

find .  -type f -iname "*.ipynb" -exec sh -c 'f=$(basename $1 .ipynb);d=$(dirname $1);echo "$d/$f"' sh {} \;
like image 1
V. Michel Avatar answered Oct 07 '22 02:10

V. Michel