Menggunakan awk
atau sed
bagaimana saya dapat memilih garis yang muncul di antara dua pola penanda yang berbeda? Mungkin ada beberapa bagian yang ditandai dengan pola ini.
Contoh: Misalkan file tersebut berisi:
abc
def1
ghi1
jkl1
mno
abc
def2
ghi2
jkl2
mno
pqr
stu
Dan pola awal abc
dan pola akhir adalah mno
Jadi, saya membutuhkan keluaran sebagai:
def1
ghi1
jkl1
def2
ghi2
jkl2
Saya menggunakan sed untuk mencocokkan pola sekali:
sed -e '1,/abc/d' -e '/mno/,$d' <FILE>
Apakah ada cara dalam sed
atau awk
melakukannya berulang-ulang sampai akhir file?
awk '/abc/{a=1}/mno/{print;a=0}a' file
.awk '/abc/{a=1} a; /mno/{a=0}' file
- dengan ini, menempatkana
kondisi sebelum/mno/
kita membuatnya mengevaluasi baris sebagai benar (dan mencetaknya) sebelum pengaturana=0
. Dengan cara ini kita bisa menghindari menulisprint
.awk '/abc/,/mno/' file
awk '/abc/{flag=1}/mno/{flag=0}flag' file
harus membuat.awk 'flag; /PAT1/{flag=1; next} /PAT1/{flag=0}' file
akan membuat.Menggunakan
sed
:The
-n
berarti pilihan tidak mencetak secara default.Pola mencari baris yang berisi just
abc
to justmno
, lalu menjalankan tindakan di{ ... }
. Tindakan pertama menghapusabc
baris; baris keduamno
; danp
mencetak garis yang tersisa. Anda dapat melonggarkan ekspresi reguler sesuai kebutuhan. Setiap baris di luar kisaranabc
..mno
tidak dicetak.sumber
-e
sed
harus dieksekusi. Jika Anda ingin atau perlu menggunakan beberapa argumen untuk memasukkan seluruh skrip, maka Anda harus menggunakan-e
sebelum setiap argumen tersebut; jika tidak, itu opsional (tapi eksplisit).d
ke semua baris hingga pertandingan pertama, dan kemudiand
ke semua baris yang dimulai dengan pertandingan kedua?Ini mungkin berhasil untuk Anda (GNU sed):
Hapus semua baris kecuali yang antara baris dimulai
abc
danmno
sumber
!d;//d
golf 2 karakter lebih baik :-) stackoverflow.com/a/31380266/895245{//!b}
mencegah yangabc
danmno
dari yang termasuk dalam output, tapi aku tidak tahu bagaimana. Bisakah Anda menjelaskan?//!b
membaca jika baris saat ini bukan salah satu baris yang cocok dengan rentang, putus dan karena itu mencetak baris tersebut jika tidak semua baris lainnya akan dihapus.golf dua karakter lebih baik daripada ppotong
{//!b};d
Garis miring kosong
//
berarti: "gunakan kembali ekspresi reguler terakhir yang digunakan". dan perintahnya melakukan hal yang sama seperti yang lebih bisa dimengerti:Ini sepertinya POSIX :
sumber
Dari tautan tanggapan sebelumnya, yang melakukannya untuk saya, berjalan
ksh
di Solaris, adalah ini:1,/firstmatch/d
: dari baris 1 hingga pertama kali Anda temukanfirstmatch
, hapus./secondmatch/,$d
: dari kemunculan pertamasecondmatch
hingga akhir file, hapus.sumber
1,
) muncul sebelumnya/firstmatch/
? Saya menduga ini juga bisa diutarakan'/firstmatch/1,d;/secondmatch,$d'
?sumber
sesuatu seperti ini berhasil untuk saya:
file.awk:
menggunakan:
awk -f file.awk data
...edit: Solusi O_o fedorqui jauh lebih baik / lebih cantik dari saya.
sumber
if (record=1)
harusif (record==1)
, yaitu ganda=
- lihat operator perbandingan melongoJawaban Don_crissti dari Tampilkan hanya teks antara 2 pola yang cocok ?
yang jauh lebih efisien daripada aplikasi AWK, lihat di sini .
sumber
Saya mencoba menggunakan
awk
untuk mencetak garis antara dua pola sementara pola2 juga cocok dengan pola1 . Dan garis pattern1 juga harus dicetak.misalnya sumber
harus memiliki keluaran
Di mana pola1 adalah
package BBB
, pola2 adalahpackage \w*
. Perhatikan bahwaCCC
itu bukan nilai yang diketahui sehingga tidak dapat dicocokkan secara harfiah.Dalam hal ini, baik @scai
awk '/abc/{a=1}/mno/{print;a=0}a' file
maupun @fedorqui tidak cocokawk '/abc/{a=1} a; /mno/{a=0}' file
untuk saya.Akhirnya saya berhasil mengatasinya dengan
awk '/package BBB/{flag=1;print;next}/package \w*/{flag=0}flag' file
, hahaSedikit lebih banyak usaha menghasilkan
awk '/package BBB/{flag=1;print;next}flag;/package \w*/{flag=0}' file
, untuk mencetak garis pola2 juga, yaitu,sumber