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>

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}'

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.  

3

Dengan GNU awkAnda dapat melakukan:

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

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.


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.


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
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.