5

I like to restrict the columns shown in ls -l command, by eliminating the first 4 columns.

ls -lh shows:

drwxr-sr-x 20 gamma alpha 4.0K May 22 13:18 Desktop
drwxr-sr-x  3 gamma alpha   22 Oct  6  2014 Eclipse
-rw-r--r--  1 gamma alpha  28K Jul 11  2014 fire
drwxr-sr-x  5 gamma alpha   48 Mar 31  2014 lb_deployment

To eliminate the first four columns, I tried ls -lh | cut -d " " -f5-. But it doesn't behave as desired:

4.0K May 22 13:18 Desktop
alpha  22 Oct  6  2014 Eclipse
alpha 28K Jul 11  2014 fire
alpha  48 Mar 31  2014 lb_deployment

I like it to look like this:

4.0K May 22 13:18 Desktop
  22 Oct  6  2014 Eclipse
 28K Jul 11  2014 fire
  48 Mar 31  2014 lb_deployment

The reason that it does not behave as desired is that, in cut I defined delimiter to be blank space (-d " "), but since the number of links (second column of \ls -lh) of the first file is a 2-digit number (20), ls -lh adds another blank space to the link counter of the files with 1-digit link counter to adjust the columns positions. And this causes cut to not behave as desired.

Any ideas on how to fix this?

2
  • have you tried leaving -d off completely? It's not working because it's treating each space as the start of a new field.
    – Bratchley
    May 23, 2015 at 0:04
  • 2
    @Bratchley without -d the cut will default to fields separated by {tab}. May 23, 2015 at 0:08

4 Answers 4

6

Pass the -o and -g options to omit the user and group columns. Since user and group names can contain spaces, you can't reliably edit them out.

There's no option to omit the permissions and link count columns. Since the first column you want to keep can start with whitespace (for right alignment), you can't use the whitespace-to-non-whitespace transition as the start criterion. Instead, use the right edge of the last column to eliminate the columns you don't want. This is safe because the first two columns can't contain embedded whitespace.

ls -lhog | sed 's/^[^ ][^ ]*  *[^ ][^ ]* //'

Explanation of the sed command:

  • s/REGEXP/REPLACEMENT/ replaces the first occurrence of the specified regular expression on each line by the specified replacement text. Here the replacement text is empty.
  • ^ at the beginning of the regexp makes it match only at the beginning of the line.
  • [^ ][^ ]* matches any non-empty sequence of characters other than a space.
  • Thus the sed command removes the first and second non-whitespace sequences, as well as the next space (but only one space at the end).
2
  • Thanks. Can you please update your answer with a brief description of what 's/^[^ ][^ ]* *[^ ][^ ]*' is doing?
    – LoMaPh
    May 23, 2015 at 0:31
  • @LoMaPh edited. May 23, 2015 at 0:36
2

This works for me:

ls -lhn | sed -r 's#^\S+(\s+\S+){3}##'

The extra -n flag to ls turns user and group names into numeric ids. As a result we get a known number of fields to strip:

-rwxr-xr-x  1 1001 1001 1.4K Mar 23 18:07 something.sh

The whitespace between each of the columns is variable but is what ls uses to align columns, so we cannot just blindly strip it out. I have chosen to strip the leading block of permissions, followed by three groups of whitespace-text then not-whitespace-text, matching the link count, uid, and gid respectively. This leaves the whitespace separating the gid from the filesize untouched so that alignment can continue to work. The sed regular expression is what implements this pattern removal. #...#...# provides the delimiters (match and replace), and the -r flag allows us to use Extended Regular Expressions. Dissecting that we have ^ matching start-of-line; the \S+ matches one or more non-whitespace characters and \s+ matches one or more whitespace characters; the brackets (...) group these two items together and the braces {3} state that the group must be repeated three times.

 4.0K Jun  6  2014 template
 4.0K May 21 17:35 stuff
    0 Mar 16 09:46 Items
 1.4K Mar 23 18:07 something.sh
  24K May 19 14:45 curtain
2
  • Thanks. Can you please explain a bit?
    – LoMaPh
    May 23, 2015 at 0:15
  • @LoMaPh for the record I've added my explanation May 23, 2015 at 13:34
0

Joining the choir, you can also use awk to blank out the columns you don't want:

[jis@localhost ~]$ ls -lh | awk '{$1=$2=$3=$4="";print}'

    4.0K Aug 19 2014 Desktop
    4.0K Jan 8 22:39 dir1
    4.0K Feb 5 20:41 Documents
    12K May 22 19:31 Downloads
    4.0K Aug 19 2014 Music
    4.0K May 3 20:00 Pictures
    4.0K Aug 19 2014 Public
    115K May 9 09:05 something.bin
    4.0K Aug 19 2014 Templates
    1 Dec 12 07:01 testLink -> .
    4.0K Aug 19 2014 Videos
[jis@localhost ~]$ 
2
  • I tried that. But it destroys the nice column structure of -ls -l. Is there any way to keep the alignments using awk?
    – LoMaPh
    May 23, 2015 at 0:20
  • 1
    What is it about the column structure you're trying to preserve? If it's just making sure everything lines up you might try piping the output through column -t to top it off. It'll still look different than a straight ls -lh though.
    – Bratchley
    May 23, 2015 at 0:24
0

A nifty solution using grep:

ls -lhn | grep -oP "^([[:graph:]]+\s){4}\K.+"

Here,

[[:graph:]] ==> all printed characters (i.e. no spaces, newlines)
\s          ==> space
{4}         ==> exactly four matches
9
  • It destroys the nice column structure of ls -l. Makes it messy.
    – LoMaPh
    May 23, 2015 at 0:07
  • updated... now it works fine... just check
    – shivams
    May 23, 2015 at 0:07
  • This breaks for user and group names containing spaces. You might get a solution using ls -lhn | ... May 23, 2015 at 0:08
  • 1
    @roaima usernames do not contain spaces... as far as I know...
    – shivams
    May 23, 2015 at 0:12
  • @shivams It just shows the first line.
    – LoMaPh
    May 23, 2015 at 0:13

You must log in to answer this question.

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