bashpipefile-extensionstring-substitutionbasename

Pipe the output of basename to string substitution


I need the basename of a file that is given as an argument to a bash script. The basename should be stripped of its file extension. Let's assume $1 = "/somefolder/andanotherfolder/myfile.txt", the desired output would be "myfile".

The current attempt creates an intermediate variable that I would like to avoid:

BASE=$(basename "$1")
NOEXT="${BASE%.*}"

My attempt to make this a one-liner would be piping the output of basename. However, I do not know how to pipe stdout to a string substitution.

EDIT: this needs to work for multiple file extensions with possibly differing lengths, hence the string substitution attempt as given above.


Solution

  • Why not Zoidberg ? Ehhmm.. I meant why not remove the ext before going for basename ?

    basename "${1%.*}"
    

    Unless of course you have directory paths with dots, then you'll have to use basename before and remove the extension later:

    echo $(basename "$1") | awk 'BEGIN { FS = "." }; { print $1 }'
    

    The awk solution will remove anything after the first dot from the filename.

    There's a regular expression based solution which uses sed to remove only the extension after last dot if it exists:

    echo $(basename "$1") | sed 's/\(.*\)\..*/\1/'
    

    This could even be improved if you're sure that you've got alphanumeric extensions of 3-4 characters (eg: mp3, mpeg, jpg, txt, json...)

    echo $(basename "$1") | sed 's/\(.*\)\.[[:alnum:]]\{3\}$/\1/'