Jadi menarik membuka file dengan cat
dan kemudian menggunakan grep
untuk mendapatkan baris yang cocok hanya membuat saya sejauh ini ketika saya bekerja dengan set log tertentu yang saya hadapi. Ini membutuhkan cara untuk mencocokkan garis ke suatu pola, tetapi hanya untuk mengembalikan bagian garis setelah pertandingan. Bagian sebelum dan sesudah pertandingan akan bervariasi secara konsisten. Saya telah bermain dengan menggunakan sed
atau awk
, tetapi belum dapat menemukan cara untuk memfilter garis untuk menghapus bagian sebelum pertandingan, atau hanya mengembalikan bagian setelah pertandingan, apakah akan bekerja. Ini adalah contoh baris yang perlu saya filter:
2011-11-07T05:37:43-08:00 <0.4> isi-udb5-ash4-1(id1) /boot/kernel.amd64/kernel: [gmp_info.c:1758](pid 40370="kt: gmp-drive-updat")(tid=100872) new group: <15,1773>: { 1:0-25,27-34,37-38, 2:0-33,35-36, 3:0-35, 4:0-9,11-14,16-32,34-38, 5:0-35, 6:0-15,17-36, 7:0-16,18-36, 8:0-14,16-32,34-36, 9:0-10,12-36, 10-11:0-35, 12:0-5,7-30,32-35, 13-19:0-35, 20:0,2-35, down: 8:15, soft_failed: 1:27, 8:15, stalled: 12:6,31, 20:1 }
Bagian yang saya butuhkan adalah segalanya setelah "macet".
Latar belakang di balik ini adalah saya bisa mengetahui seberapa sering sesuatu berhenti:
cat messages | grep stalled | wc -l
Yang perlu saya lakukan adalah mencari tahu berapa kali simpul tertentu terhenti (ditunjukkan oleh bagian sebelum masing-masing titik dua setelah "terhenti". Jika saya hanya memahami untuk itu (yaitu 20 :) mungkin akan mengembalikan garis yang telah gagal lunak, tetapi tidak ada warung, yang tidak membantu saya. Saya hanya perlu memfilter bagian yang macet sehingga saya kemudian dapat mencari simpul tertentu dari yang sudah macet.
Untuk semua maksud dan tujuan, ini adalah sistem freebsd dengan utilitas inti GNU standar, tetapi saya tidak dapat menginstal apa pun tambahan untuk membantu.
sumber
sed
solusinya dan jangan perlakukan whitespace secara khusus.Jawaban:
Alat kanonik untuk itu adalah
sed
.Penjelasan detail:
-n
artinya tidak mencetak apa pun secara default.-e
diikuti oleh perintah sed.s
adalah perintah penggantian pola.^.*stalled:
cocok dengan pola yang Anda cari, ditambah teks sebelumnya (.*
artinya teks apa pun, dengan inisial yang^
mengatakan bahwa kecocokan dimulai pada awal baris). Perhatikan bahwa jikastalled:
terjadi beberapa kali di telepon, ini akan cocok dengan kejadian terakhir.stalled:
, digantikan oleh string kosong (yaitu dihapus).p
berarti mencetak garis yang diubah.Jika Anda ingin mempertahankan bagian yang cocok, gunakan referensi-ulang:
\1
di bagian pengganti menunjukkan apa yang ada di dalam grup\(…\)
dalam pola. Di sini, Anda dapat menulisstalled:
lagi di bagian pengganti; fitur ini berguna ketika pola yang Anda cari lebih umum daripada string sederhana.Terkadang Anda ingin menghapus bagian dari garis setelah pertandingan. Anda dapat memasukkannya dalam pertandingan dengan memasukkan
.*$
di akhir pola (teks apa pun.*
diikuti pada akhir baris$
). Kecuali jika Anda menempatkan bagian itu dalam grup yang Anda referensi di teks pengganti, akhir baris tidak akan berada di output.Sebagai ilustrasi lebih lanjut tentang grup dan referensi, perintah ini menukar bagian sebelum pertandingan dan bagian setelah pertandingan.
sumber
sed … <messages
, karena Anda ingin memproses data dari file. Untuk bertindak atas data yang dihasilkan oleh perintah lain, Anda akan menggunakan pipa:somecommand | sed …
.sed 's/^.*stalled//'
karena-r
ini khusus untuk Linux dan tidak bekerja pada sistem lain seperti macOS dan di sini Anda tidak mendapatkan manfaat apa pun dari itu.Alat kanonik lain yang sudah Anda gunakan
grep
::Sebagai contoh:
Memiliki hasil yang sama dengan opsi kedua Gilles:
The
-o
bendera mengembalikan--only-matching
bagian dari ekspresi, sehingga tidak seluruh baris yang - tentu saja - yang biasanya dilakukan oleh grep.Untuk menghapus "terhenti:" dari output, kita dapat menggunakan alat kanonik ketiga, potong:
The
cut
perintah menggunakan pembatas:
dan mencetak lapangan 2 sampai akhir. Ini masalah preferensi tentu saja, tetapicut
sintaks yang saya temukan sangat mudah diingat.sumber
-o
opsi! Saya ingin menunjukkan bahwagrep
tidak mengenalinya\n
sebagai baris baru, jadi contoh pertama Anda hanya cocok dengann
karakter pertama . Misalnya,echo "Hello Anne" | grep -o 'A[^\n]*'
mengembalikan stringA
. Namun,echo "Hello Anne" | grep -o 'A.*'
mengembalikan yang diharapkanAnne
, karena.
cocok dengan karakter apa pun kecuali baris baru.cut
pembatas-d':'
dihapus oleh @poige. Saya merasa lebih mudah diingat dengan kutipan, misalnya dengan-d' '
atau-d';'
.-f 2
juga. Serius, kenapa tidak?;
daripada colon:
akan diartikan berbeda jika tidak dikutip. Tentu saja itu perilaku logis, tapi tetap saja saya suka mengandalkan memori otot. Saya tidak suka mengutip pembatas satu kali tetapi tidak pada waktu yang lain. Hanya preferensi pribadi, seperti yang saya katakan sebelumnya: lebih mudah diingat..*
diperlukan, bekerja dengan baik untuk saya:cat filename | grep 'Return only this line xyz text' | grep -o 'xyz.*'
pengembalianxyz text
Saya biasa
ifconfig | grep eth0 | cut -f3- -d:
mengambil inidan membuatnya terlihat seperti ini
sumber
cat /sys/class/net/*/address
, tidak perlu parsing.Namun alat kanonik lain yang Anda pertimbangkan
awk
dapat digunakan dengan baris berikut:Penjelasan detail:
-F
mendefinisikan pemisah untuk garis, yaitu, "terhenti". Semuanya sebelum pemisah ditangani$1
dan semuanya setelah dengan$2
./reg-ex/
Menelusuri persamaan reguler yang cocok, dalam hal ini "terhenti".{print $<n>}
- mencetak n kolom. Karena pemisah Anda didefinisikan sebagai macet, segala sesuatu setelah macet dianggap sebagai kolom kedua.sumber