Baris cetak setelah kemunculan yang ke-1 kecocokan

8

Saya mencari untuk menampilkan baris 4598 di file berikut. Secara efektif saya ingin menampilkan garis SETELAH terjadinya pertandingan. Dalam hal ini, garis setelah kemunculan ke - 3 dari <Car>. Bagaimana saya melakukannya?

<Car>
10456
</Car>
<Car>
70192
</Car>
<Car>
4598
</Car>
DJ180
sumber
1
Sementara itu mungkin mungkin untuk mencapai apa yang Anda inginkan menggunakan sed, awkatau bahkan grep, itu dianjurkan untuk menggunakan parser XML.
devnull
XML hanya digunakan untuk contoh, teks dapat berupa format apa saja
DJ180

Jawaban:

10
awk -v n=3 '/<Car>/ && !--n {getline; print; exit}'

Atau:

awk '/<Car>/ && ++n == 3 {getline; print; exit}'

Untuk meneruskan pola pencarian sebagai variabel:

var='<car>'
PATTERN="$var" awk -v n=3 '
  $0 ~ ENVIRON["PATTERN"] && ++n == 3 {getline; print; exit}'

Di sini menggunakan ENVIRONalih-alih -vsebagai -vmemperluas urutan backslash-escape dan backslash sering ditemukan dalam ekspresi reguler (jadi perlu digandakan dengan -v).

GNU awk4.2 atau lebih baru memungkinkan Anda menetapkan variabel sebagai regexps yang diketik dengan kuat . Selama mode POSIX-nya tidak diaktifkan (misalnya melalui $POSIXLY_CORRECTvariabel lingkungan, Anda dapat melakukan:

# GNU awk 4.2 or above only, when not in POSIX mode
gawk -v n=3 -v pattern="@/$var/" '
  $0 ~ pattern && ++n == 3 {getline; print; exit}'
Stéphane Chazelas
sumber
Cara meneruskan pola pencarian juga sebagai variabel dalam perintah di atas
WanderingMind
@ MengembaraMind, lihat edit.
Stéphane Chazelas
4

Inilah perl satu:

perl -ne 'print && exit if $c==3; $c++ if /<Car>/;' file 

Dengan GNU grep, Anda juga dapat menguraikan hasilnya seperti:

grep -A 1 -m 3 '<Car>' file | tail -n 1

Dari man grep:

-A NUM, --after-context=NUM
          Print NUM lines of trailing context after matching lines.  
          Places a line containing a group separator (--) between 
          contiguous  groups  of  matches.          
-m NUM, --max-count=NUM
          Stop reading a file after NUM matching lines.  
terdon
sumber
3

Dengan GNU awkAnda dapat melakukan:

gawk -v RS='</Car>' 'NR==3 && $0=$2' inputFile
jaypal singh
sumber
1

Inilah cara lain dengan sed:

sed -n '/<Car>/{x;/.\{2\}/{x;$!{n;p};q};s/.*/&./;x}' infile

Ini menggunakan ruang tunggu untuk menghitung.
Setiap kali bertemu garis yang cocok <Car>itu, ia xmengubah buffer dan memeriksa apakah ada persis N-1 kejadian karakter dalam buffer terus. Jika centang berhasil, maka ia xberubah lagi, dan jika tidak pada baris terakhir, ia menarik ngaris ext dan pmematahkan ruang pola lalu qmenggunakan. Kalau tidak, itu hanya menambahkan .karakter lain ke ruang penahanan dan xperubahan e kembali.

don_crissti
sumber
0

Inilah solusi baris perintah sederhana.

grep -F -A1 '<Car>' filename | grep -E -v '<Car>|--' | tail -n +3 |head -n +1

Jika Anda mengubah nilai +3 setelahnya tail, Anda dapat menentukan baris ke-n apa saja.

bsd
sumber
Tidak yakin mengapa Anda menambahkan tag, sed, awk, dll. Jika Anda ingin solusi menggunakan aplikasi tertentu, utilitas maka Anda harus menentukan ini dalam pertanyaan atau judul.
bsd