Search code examples
bashsedfilenameslstr

List of extensions of filenames in bash script in one line


I currently have the following line of code:

ls /some/dir/prefix* | sed -e 's/prefix.//' | tr '\n' ' '

Which does achieve what I want it to do:

  • Get list of files starting with prefix
  • Remove path and prefix from each string
  • Remove newlines and replace with spaces for later processing.

For example:

/some/dir/prefix.hello
/some/dir/prefix.world

Should become

hello world

But I feel like there's a nicer way of doing this. Is there a better way to do this in one line?


Solution

  • Here is a two-liner using just built-ins that does it:

    fnames=(some/dir/prefix*)
    echo "${fnames[@]##*.}"
    

    And here's how this works:

    • fnames=(some/dir/prefix*) creates an array with all the files starting with prefix and avoids all the problems that come with parsing ls
    • echo "${fnames[@]##*.}" is a combination of two parameter expansions: ${fnames[@]} prints all array elements, and the ##*. part removes the longest match of anything that ends with . from each array element, leaving just the extension

    If you're hell-bent on a one-liner, just join the two commands with &&.