On Wed, Mar 31, 2010 at 11:03:17AM -0600, Bob Proulx wrote: > Or with GNU sed using the \+ extension: > > FILENAME=$(ls | tail --lines=1 | sed 's/\.[^.]\+$//') > > I assume that 'ls' isn't what you actually are doing, that you have > reduced the test case to something smaller (thank you for that!) > because the shell can list the directory itself.
Such optimism. Just in case, it needs to be pointed out that using ls in this way is NOT a safe operation, since filenames may contain newlines (or other characters that ls may choose to represent with a ? instead of leaving intact, depending on the implementation). Newlines will completely break any line-based approach, and characters that are munged into ? will break anything that relies on the output of ls for that filename. > for f in *;do FILENAME=$f; done > ( Or even: for FILENAME in *;do : ; done ) > > And you could then slip in your variable manipulation right there. > > for f in *;do FILENAME=${f%.*}; done > echo $FILENAME echo "$FILENAME" of course; or printf "%s\n" "$FILENAME" for 100% safety. The approach that immediately sprang to mind for me was to use an array: files=(*); lastfile=${fil...@]:(-1)}; lastfile=${lastfile%.*} That uses more memory, as it stores all the filenames. But if you need more than just the one filename, it may pay off.