Menggunakan OPEN STEP 4.2 OS ... Saat ini saya menggunakan sed
Perintah berikut :
sed -n '1,/141.299.99.1/p' TESTFILE | tail -3
Perintah ini akan menemukan satu instance dalam file dengan ip 141.299.99.1 dan juga menyertakan 3 baris sebelumnya yang semuanya baik, dengan pengecualian bahwa saya juga ingin menemukan semua instance IP dan 3 baris sebelumnya dan bukan hanya yang pertama.
Jawaban:
Berikut adalah upaya untuk meniru
grep -B3
menggunakan sed moving window, berdasarkan contoh sed GNU ini (tapi semoga sesuai dengan POSIX - dengan pengakuan ke @ StéphaneChazelas):Dua ekspresi pertama prime buffer pola multi-line dan memungkinkannya untuk menangani kasus tepi di mana ada kurang dari 3 baris konteks sebelumnya sebelum pertandingan pertama. Ekspresi tengah (pencocokan regex) mencetak garis dari atas jendela sampai teks pencocokan yang diinginkan telah berdesir melalui buffer pola. Final
$!N;D
menggulung jendela dengan satu baris kecuali ketika mencapai akhir input.sumber
-e
tidak spesifik GNU. Untuk menjadi POSIX / portable, Anda memang membutuhkannya karena tidak ada apa pun setelahnya}
(dan Anda memerlukannya;
sebelum itu).-e '1h;2,4{H;g;}' -e '1,3d'
? Saya tidak memiliki sistem non-GNU untuk diuji (dan--posix
saklar sed GNU tampaknya tidak peduli).sed
dari heirloom toolchest yang merupakan turunan dari perangkat Unix tradisional. POSIX / Unix spec untuksed
di pubs.opengroup.org/onlinepubs/9699919799/utilities/sed.htmlgrep
akan melakukan pekerjaan ini dengan lebih baik:The
-B 3
sarana untuk mencetak tiga baris sebelum setiap pertandingan. Ini akan mencetak di--
antara setiap kelompok garis. Untuk menonaktifkannya, gunakan--no-group-separator
juga.The
-B
option didukung oleh GNUgrep
dan sebagian besar versi BSD juga ( OSX , FreeBSD , OpenBSD , NetBSD ), tapi secara teknis bukan pilihan standar.sumber
Dengan
sed
Anda bisa melakukan sliding window.Itu berhasil. Tapi waspadalah -
bash
perilaku gila ekspansi!
bahkan ketika dikutip !!! ke dalam string perintah dari sejarah perintah Anda mungkin membuatnya sedikit gila. Awali perintah denganset +H;
jika Anda menemukan ini masalahnya. Untuk kemudian mengaktifkannya kembali (tapi mengapa ???) lakukanset -H
sesudahnya.Itu, tentu saja, hanya akan berlaku jika Anda sedang menggunakan
bash
- meskipun saya tidak percaya Anda. Saya cukup yakin Anda bekerja dengancsh
- (yang kebetulan shell yang perilaku gilabash
ditiru dengan ekspansi sejarah, tapi mungkin tidak terlalu ekstrem shell c mengambilnya) . Jadi mungkin suatu\!
harus bekerja. Saya harap.Ini semua kode portabel: POSIX menjelaskan tiga operatornya sebagai berikut: (meskipun perlu dicatat bahwa saya hanya mengonfirmasi deskripsi ini sudah ada sejak tahun 2001)
Jadi pada baris pertama Anda menambahkan garis ekstra ke ruang pola, sehingga terlihat seperti ini:
Kemudian pada baris pertama dan setiap baris sesudahnya - kecuali yang terakhir - Anda menambahkan baris lain ke ruang pola. Jadi sepertinya ini:
Jika alamat ip Anda ditemukan di dalam diri Anda
P
hingga baris baru pertama, maka cukup baris 1 di sini. Di akhir setiap siklus, AndaD
mengelakan hal yang sama dan memulai kembali dengan yang tersisa. Jadi siklus selanjutnya terlihat seperti:...dan seterusnya. Jika ip Anda dapat ditemukan pada salah satu dari tiga yang tertua akan dicetak - setiap saat. Jadi, Anda selalu hanya tiga baris di depan.
Ini contoh singkatnya. Saya akan mencetak buffer tiga baris untuk setiap angka yang diakhiri dengan nol:
Yang itu sedikit lebih rumit daripada kasus Anda karena saya harus berganti dari
0\n
baris baru atau0$
akhir pola ruang untuk lebih mirip masalah Anda - tetapi mereka agak berbeda dalam hal ini membutuhkan jangkar - yang dapat sedikit sulit dilakukan karena pola-ruang terus bergeser.Saya menggunakan kasus aneh 10 dan 52 untuk menunjukkan bahwa selama jangkar fleksibel maka outputnya juga. Sepenuhnya mudah dibawa, saya dapat mencapai hasil yang sama dengan mengandalkan algoritma dan melakukan:
Dan memperluas pencarian sambil membatasi jendela saya - dari 0 hingga 9 dan 0 dan dari 3 baris menjadi dua.
Bagaimanapun, Anda mendapatkan idenya.
sumber
sed '...' $filename
. By the way - saya meninggalkan periode dari string pencarian Anda sendiri, tetapi itu sebenarnya bukan periode dalam suatu pola - yang mewakili karakter tunggal. Anda mungkin harus melakukannyaoct\.oct\.oct\.oct
untuk melarikan diri sehingga mereka hanya cocok dengan periode.Karena Anda menyebutkan bahwa Anda tidak memiliki
-B
opsi untukgrep
, Anda dapat menggunakan Perl (misalnya) untuk membuat jendela geser 4 baris:Jawaban Ramesh melakukan hal serupa dengan
awk
.sumber
Jika tersedia, Anda dapat menggunakan pcregrep :
sumber
Anda dapat menerapkan pendekatan dasar yang sama dengan jawaban non-grep di shell itu sendiri (ini mengasumsikan shell yang relatif baru yang mendukung
=~
):Atau, Anda bisa menghirup seluruh file menjadi array:
sumber
Jika sistem Anda tidak mendukung
grep
konteks, Anda dapat mencoba ack-grep sebagai gantinya:ack
adalah alat seperti grep, dioptimalkan untuk programmer.sumber
perl
, Anda bisa menggunakanack
.Dalam
awk
solusi ini , array digunakan yang akan selalu berisi 3 baris sebelum pola saat ini. Oleh karena itu, ketika pola dicocokkan, isi array bersama dengan pola saat ini dicetak.Pengujian
Setelah saya menjalankan perintah, hasilnya adalah,
sumber
Dalam sebagian besar dari ini,
/141.299.99.1/
juga akan cocok (misalnya)141a299q99+1
atau141029969951
karena.
dalam ekspresi reguler dapat mewakili karakter apa pun.Menggunakan
/141[.]299[.]99[.]1/
lebih aman, dan Anda dapat menambahkan konteks tambahan di awal dan akhir dari seluruh regexp untuk memastikan tidak cocok3141.
,.12
,.104
, dllsumber