55

I want to grep the output of my ls -l command:

-rw-r--r--   1 root root       1866 Feb 14 07:47 rahmu.file
-rw-r--r--   1 rahmu user     95653 Feb 14 07:47 foo.file
-rw-r--r--   1 rahmu user   1073822 Feb 14 21:01 bar.file

I want to run grep rahmu on column $3 only, so the output of my grep command should look like this:

-rw-r--r--   1 rahmu user     95653 Feb 14 07:47 foo.file
-rw-r--r--   1 rahmu user   1073822 Feb 14 21:01 bar.file

What's the simplest way to do it? The answer must be portable across many Unices, preferably focusing on Linux and Solaris.

NB: I'm not looking for a way to find all the files belonging to a given user. This example was only given to make my question clearer.

2
  • 6
    Note that parsing the output of ls is inherently fragile (think what happens if a user name contains whitespace — and yes, this happens on some platforms). Use find instead. Feb 16, 2012 at 1:47
  • This doesn't answer the title question, but I'll mention that the --printf option to stat may come in handy in places where you might otherwise consider parsing ls. But usually, find is what you want (as @Gilles mentioned).
    – Wildcard
    Jan 17, 2018 at 9:52

5 Answers 5

70

One more time awk saves the day!

Here's a straightforward way to do it, with a relatively simple syntax:

ls -l | awk '{if ($3 == "rahmu") print $0;}'

or even simpler: (Thanks to Peter.O in the comments)

ls -l | awk '$3 == "rahmu"' 
3
  • 10
    Or: ls -l | awk '$3=="rahmu"' ... and by the way, the opening ( bracket should be after if ... awk '{if($3 ...'
    – Peter.O
    Feb 15, 2012 at 15:11
  • 3
    @Peter.O +1 from me. Your command is more succinct, correct, since print is the default for an awk match.
    – bsd
    Feb 15, 2012 at 16:06
  • To avoid localization issues (date format affects column order) it is often suggested to ensure standard format and language: LANG=C ls -l | awk ...
    – fheub
    Feb 16, 2012 at 10:26
27

If you are looking to match only part of the string on a given column, you can use advice from https://stackoverflow.com/questions/17001849/awk-partly-string-match-if-column-partly-matches

some_command | awk '$6 ~ /string/'
2
  • 2
    This should be the top answer
    – PejoPhylo
    Nov 7, 2018 at 8:49
  • work great. thanks.
    – logbasex
    Sep 23, 2022 at 18:34
12

If by column, you mean fixed-size column, you could:

ls -l | grep "^.\{15\}rahmu"

where ^ means the beginning of the line, . means any character and \{15\} means exactly 15 occurrences of the previous character (any character in this case).

1
  • One can also do ls -l | grep -E '^.{15}rahmu' because -E is defined by POSIX anyway and then you don't have to escape the command group character.
    – Akito
    May 14, 2020 at 13:03
6

I know I'm late to the party, but I believe a very general solution to this problem is to use awk with regular expressions like so:

awk '$3~/rahmu/{print}' input_file

The part enclosed by '//' can be any kind of regular expression.

1

To grep based on single username column (and print only files), you can try:

ls -la | grep "^-\S\+\s\+\S\+\s\+rahmu"

For directories, change - into d, for any type remove -.

It basically selects each column by \S\+\s\+ which matches a non-space characters followed by a space characters, so we're matching three first columns and then the username.

You must log in to answer this question.

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