Is there a way I can do this? For example if a gets a long name like:


Can I "upgrade" over from ls to ls -l given that I have a name of a file or directory that is longer than than say, 20 characters?

Is there a way to set up a bash function in my .bashrc to do this? I'll call the resulting function lls().

@tripleee asked:

Do you want ls -l when the input file name is long? Why? It will make the output longer, not shorter. What if you receive a mix of long and short filenames?

I want it more so that reading the long filenames are systematized to a list (and easier for me to digest and read going down a fixed column); for a mix of long and short filenames, I would default to the list format.


There's no builtin option in ls that does what you want. You'd have to parse the output then restart if "long" filenames are found, or do something like:

$ ls ??????????* >& /dev/null && ls -l || ls

(Put as many ? as your length limit. You can set that up as an alias.)

Why don't you simply use ls -1? (That's a one, not a lowercase L.) It always lists files in a single column. (Or pipe ls to more or less, which also goes to single column display.) Or use find with -maxdepth 1.

  • I did not know about ls -1, thanks! Also, great answer, that's a neat way of going about doing what I wanted – Kevin Lee Jul 17 '12 at 4:07
if [ $(ls "$@" | ( max=0; while read l ; do len=${#l} ; [[ $max -lt $len ]] && max=$len; done; echo $max )) -gt 20 ]
    ls "$@"
    ls -l "$@"

or, thanks to manatwork suggestion, this much simpler way which assumes GNU wc is available:

[[ $(ls "$@" | wc -L) -gt 20 ]] && ls "$@" || ls -l "$@"
  • 1
    While assuming GNU tools, would not be easier using wc's -L or --max-line-length switch? – manatwork Jul 16 '12 at 9:47
  • Even if wc's -L switch is not available, using wc for counting is still shorter and faster: ls | tr -c 'a\n' 'a' | sort -r | head -1 | wc -m. But there is a small inconvenience: this will output actual max length+1. – manatwork Jul 16 '12 at 9:59
  • @manatwork Thanks for the comments, reply updated. – jlliagre Jul 16 '12 at 10:26

This is my independent attempt of what I wanted:

  opt="   "      
  for i in $(ls -l | tr -s " " | cut -d' ' -f9)  
    count=$(echo $i | wc -m)  
     if [ $count -gt 20 ] ; then    
       opt=" -l"; break;           
  ls $opt

I placed this in my .bashrc. This does require the use of tr, cut, and wc though.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.