Jak uruchomić grep na pojedynczej kolumnie?

42

Chcę grepować wyjście mojego ls -lpolecenia:

-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

Chcę uruchomić tylko grep rahmuw kolumnie $ 3, więc wynik mojej grepkomendy powinien wyglądać następująco:

-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

Jak najprościej to zrobić? Odpowiedź musi być przenośna na wiele Uniksów, najlepiej na Linuksie i Solarisie.

NB: Nie szukam sposobu na znalezienie wszystkich plików należących do danego użytkownika. Ten przykład został podany tylko w celu wyjaśnienia mojego pytania.

rahmu
źródło
5
Zauważ, że parsowanie wyniku lsjest z natury delikatne (pomyśl, co się stanie, jeśli nazwa użytkownika zawiera spacje - i tak, dzieje się to na niektórych platformach). Użyj findzamiast tego.
Gilles „SO- przestań być zły”
To nie odpowiada na pytanie tytułowe, ale wspomnę, że --printfopcja ta statmoże się przydać w miejscach, w których w innym przypadku można rozważyć analizę ls. Ale zwykle findjest to, czego chcesz (jak wspomniano @Gilles).
Wildcard

Odpowiedzi:

49

Jeszcze jeden czas awkoszczędza dzień!

Oto prosty sposób na zrobienie tego ze stosunkowo prostą składnią:

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

lub nawet prościej: (Dzięki Peter.O w komentarzach)

ls -l | awk '$3 == "rahmu"' 
rahmu
źródło
9
Lub: ls -l | awk '$3=="rahmu"'... a przy okazji, (klamra otwierająca powinna być po if...awk '{if($3 ...'
Peter.O
3
@ Peter.O +1 ode mnie. Twoje polecenie jest bardziej zwięzłe, poprawne, ponieważ druk jest domyślny dla dopasowania awk.
bsd
Aby uniknąć problemów z lokalizacją (format daty wpływa na kolejność kolumn), często LANG=C ls -l | awk ...
zaleca
11

Jeśli przez kolumnę rozumiesz kolumnę o stałym rozmiarze, możesz:

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

gdzie ^oznacza początek linii, .oznacza dowolny znak i \{15\}oznacza dokładnie 15 wystąpień poprzedniego znaku (w tym przypadku dowolny znak).

jfg956
źródło
2

Wiem, że jestem spóźniony na imprezę, ale uważam, że bardzo ogólnym rozwiązaniem tego problemu jest użycie awk z wyrażeniami regularnymi:

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

Część ujęta w „//” może być dowolnym wyrażeniem regularnym.

PejoPhylo
źródło
1

Aby grepować na podstawie pojedynczej kolumny nazwy użytkownika (i drukować tylko pliki), możesz spróbować:

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

W przypadku katalogów zmień -na d, usuń dowolny typ -.

Zasadniczo wybiera każdą kolumnę, według \S\+\s\+której pasują znaki spacji, a następnie spacje, więc dopasowujemy trzy pierwsze kolumny, a następnie nazwę użytkownika.

kenorb
źródło