Preserving multi-column output from ls when paging

By default, ls displays its output in multiple columns, but when it's sent to a pager such as less it's reformatted as a single column. Is there any way I can page the original, multiple-column output and preserve the formatting?


There are two options

   -C     list entries by columns
   -x     list entries by lines instead of by columns

the first shows the output in columns, where each column comes after the preceding (from the sorting point of view):

enzotib@acer:tmp$ touch {10..99}
enzotib@acer:tmp$ ls -C | less
10  15  20  25  30  35  40  45  50  55  60  65  70  75  80  85  90  95
11  16  21  26  31  36  41  46  51  56  61  66  71  76  81  86  91  96
12  17  22  27  32  37  42  47  52  57  62  67  72  77  82  87  92  97
13  18  23  28  33  38  43  48  53  58  63  68  73  78  83  88  93  98
14  19  24  29  34  39  44  49  54  59  64  69  74  79  84  89  94  99

The second option puts the first elements on the first row, then on the second row and so on:

enzotib@acer:tmp$ ls -x | less
10  11  12  13  14  15  16  17  18  19  20  21  22  23  24  25  26  27  28  29
30  31  32  33  34  35  36  37  38  39  40  41  42  43  44  45  46  47  48  49
50  51  52  53  54  55  56  57  58  59  60  61  62  63  64  65  66  67  68  69
70  71  72  73  74  75  76  77  78  79  80  81  82  83  84  85  86  87  88  89
90  91  92  93  94  95  96  97  98  99

When piping to a pager, the terminal width and the color formatting are not taken into account from ls. To force this you can do

ls -Cw $COLUMNS --color | less -r

where -r option to less is needed to correctly interpret ANSI color sequences.
Putting this line into a script do not work, because COLUMNS is not exported to subshells. Two work-around can be used

  1. export COLUMNS in your ~/.bashrc

  2. implement that line as a function or an alias in ~/.bashrc

    myls() {
        ls -Cw $COLUMNS --color "$@" | less -r
    }