3

I have a file path /home/test/domain/example.txt It can also be completely different in length and file extension. For example:

/reallylongpath/example/longername.vb

I need to remove the extension name '.' and after, and I need to delete everything other than the file name. The two examples above I would need example and longername.

I was assuming to go to the last occurrence of '/' but not sure.

I am looking to do this using bash.

3
  • Bashguide: Parameter Expansion Nov 3, 2020 at 17:08
  • It would be easier in zsh (and even csh/tcsh where the feature comes from though you wouldn't want to use those these days): $file:t:r (root name of the tail of the file). That's also available in vim. bash has it for history substitution (like echo !:$:t:r for the root of tail of last word in previous command line) but not parameter expansion unfortunately. Nov 3, 2020 at 17:16
  • 5
    Does this answer your question? How to get only filename using sed
    – thanasisp
    Nov 3, 2020 at 17:29

2 Answers 2

7

For a fixed extension, the basename utility could be used to do this:

$ f=/home/test/domain/example.txt
$ basename -- "$f" .txt
example

But since you have arbitrary extensions, you need to explicitly pick the last extension to pass to basename. The shell's parameter expansions can be used here:

$ basename -- "$f" ".${f##*.}"
example

Or, while we're at it, use parameter expansions for both removals.

$ x="${f##*/}"; x="${x%.*}"; echo "$x"
example

${var##pattern} takes var with the longest prefix matching pattern removed. With %% it takes the suffix instead, and with one # or % the shortest prefix or suffix.

If you consider something like .txt.gz a single expansion to be removed, you could use x="${x%%.*}" (with a double %%) instead.

Note that the last solution will give an empty string as output, if the given path ends in a /, while basename would ignore trailing slashes. The other case that needs care is where the directory names can also contain dots, so something like /home/test/domain.orig/example.txt.gz, or where the filename contains no dots at all. (I didn't double check all those cases.)

For discussion on related issues, see:

0
basename /reallylongpath/example/longername.vb |cut -d"." -f1

EDIT: this will fail in case of '.' in the filename. However

basename /reallylongpath/example/lo.ngername.vb |rev| cut -d"." -f2- |rev

will provide you with the correct

lo.ngername

Not the answer you're looking for? Browse other questions tagged .