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

69

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.

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.