Bagaimana menjalankan grep pada satu kolom?

42

Saya ingin menerima output dari ls -lperintah saya :

-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

Saya ingin menjalankan hanya grep rahmupada kolom $ 3, sehingga output dari grepperintah saya akan terlihat seperti ini:

-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

Apa cara paling sederhana untuk melakukannya? Jawabannya harus portabel di banyak Unices, lebih disukai berfokus pada Linux dan Solaris.

NB: Saya tidak mencari cara untuk menemukan semua file milik pengguna tertentu. Contoh ini hanya diberikan untuk membuat pertanyaan saya lebih jelas.

rahmu
sumber
5
Perhatikan bahwa parsing output lsinheren rapuh (pikirkan apa yang terjadi jika nama pengguna berisi spasi putih - dan ya, ini terjadi pada beberapa platform). Gunakan findsebagai gantinya.
Gilles 'SANGAT berhenti menjadi jahat'
Ini tidak menjawab pertanyaan judul, tetapi saya akan menyebutkan bahwa --printfopsi untuk statberguna di tempat-tempat di mana Anda mungkin mempertimbangkan untuk parsing ls. Tapi biasanya, finditulah yang Anda inginkan (seperti yang disebutkan @Gilles).
Wildcard

Jawaban:

49

Sekali lagi awkmenghemat hari!

Berikut cara mudah untuk melakukannya, dengan sintaks yang relatif sederhana:

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

atau bahkan lebih sederhana: (Terima kasih kepada Peter.O dalam komentar)

ls -l | awk '$3 == "rahmu"' 
rahmu
sumber
9
Atau: ls -l | awk '$3=="rahmu"'... dan omong-omong, (braket pembuka harusnya setelah if...awk '{if($3 ...'
Peter.O
3
@ Peter.O +1 dari saya. Perintah Anda lebih ringkas, benar, karena cetak adalah default untuk pertandingan awk.
bsd
Untuk menghindari masalah lokalisasi (format tanggal mempengaruhi urutan kolom) sering disarankan untuk memastikan format dan bahasa standar:LANG=C ls -l | awk ...
fheub
11

Jika menurut kolom, maksud Anda adalah kolom ukuran tetap, Anda dapat:

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

di mana ^berarti awal dari baris, .berarti karakter apa pun dan \{15\}berarti persis 15 kemunculan karakter sebelumnya (karakter apa pun dalam kasus ini).

jfg956
sumber
2

Saya tahu saya terlambat ke pesta, tapi saya percaya solusi yang sangat umum untuk masalah ini adalah menggunakan awk dengan ekspresi reguler seperti:

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

Bagian yang dilingkupi oleh '//' dapat berupa ekspresi reguler apa pun.

PejoPhylo
sumber
1

Untuk mengambil berdasarkan kolom nama pengguna tunggal (dan hanya mencetak file), Anda dapat mencoba:

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

Untuk direktori, ubah -menjadi d, untuk semua jenis hapus -.

Ini pada dasarnya memilih setiap kolom \S\+\s\+yang cocok dengan karakter non-spasi diikuti oleh karakter spasi, jadi kami mencocokkan tiga kolom pertama dan kemudian nama pengguna.

kenorb
sumber