3

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

i-have-names-that-are-too-long-to-describe/
i-have-names-that-are-too-long-to-describe-2/
i-have-names-that-are-too-long-to-descri-3/

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.

3 Answers 3

3

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.

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, 2012 at 4:07
2
if [ $(ls "$@" | ( max=0; while read l ; do len=${#l} ; [[ $max -lt $len ]] && max=$len; done; echo $max )) -gt 20 ]
then
    ls "$@"
else
    ls -l "$@"
fi

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

[[ $(ls "$@" | wc -L) -gt 20 ]] && ls "$@" || ls -l "$@"
3
  • 1
    While assuming GNU tools, would not be easier using wc's -L or --max-line-length switch?
    – manatwork
    Jul 16, 2012 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, 2012 at 9:59
  • @manatwork Thanks for the comments, reply updated.
    – jlliagre
    Jul 16, 2012 at 10:26
0

This is my independent attempt of what I wanted:

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

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

You must log in to answer this question.

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