Dòng in sau khi xuất hiện lần thứ n của trận đấu


8

Tôi đang tìm cách hiển thị dòng 4598 trong tập tin sau. Thực tế, tôi muốn hiển thị dòng SAU lần xuất hiện thứ n của trận đấu. Trong trường hợp này, dòng sau lần xuất hiện thứ 3 của <Car>. Làm thế nào để tôi đi về điều này?

<Car>
10456
</Car>
<Car>
70192
</Car>
<Car>
4598
</Car>

1
Trong khi nó có thể là có thể đạt được những gì bạn muốn sử dụng sed, awkhoặc thậm chí grep, đó là khuyến khích để làm cho việc sử dụng một phân tích cú pháp XML.
devnull

XML chỉ được sử dụng cho ví dụ, văn bản có thể là bất kỳ định dạng nào
DJ180

Câu trả lời:


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

Hoặc là:

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

Để vượt qua mẫu tìm kiếm dưới dạng một biến:

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

Ở đây sử dụng ENVIRONthay vì -vnhư -vnở chuỗi xuyệc ngược-thoát và backslashes thường được tìm thấy trong biểu thức thông thường (như vậy sẽ cần phải được tăng gấp đôi với -v).

GNU awk4.2 trở lên cho phép bạn gán các biến dưới dạng biểu thức chính được gõ mạnh . Miễn là chế độ POSIX của nó không được bật (ví dụ thông qua $POSIXLY_CORRECTbiến môi trường, bạn có thể thực hiện:

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

Cách vượt qua mẫu tìm kiếm cũng như một biến trong lệnh trên
WanderingMind

@WanderingMind, xem chỉnh sửa.
Stéphane Chazelas 17/05/2016

4

Đây là một perl one:

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

Với GNU grep, bạn cũng có thể phân tích cú pháp đầu ra của nó như:

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

Từ 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

Với GNU awkbạn có thể làm:

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

1

Đây là một cách khác với sed:

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

Đây là sử dụng không gian giữ để đếm.
Mỗi lần nó gặp một dòng khớp với <Car>nó, e xsẽ thay đổi bộ đệm và kiểm tra xem có chính xác N-1 xuất hiện của một ký tự trong bộ đệm giữ hay không. Nếu kiểm tra thành công, nó sẽ xthay đổi một lần nữa và nếu không ở dòng cuối cùng, nó sẽ kéo vào ndòng ext và pgợi ý không gian mẫu sau đó là quits. Nếu không, nó chỉ thêm một .char khác vào không gian giữ và e xthay đổi lại.


0

Đây là một giải pháp dòng lệnh đơn giản.

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

Nếu bạn thay đổi giá trị +3 sau tail, bạn có thể chỉ định bất kỳ dòng thứ n nào.


Không chắc chắn lý do tại sao bạn đã thêm các thẻ, sed, awk, v.v. Nếu bạn muốn một giải pháp sử dụng một ứng dụng cụ thể, tiện ích thì bạn nên chỉ định điều này trong câu hỏi hoặc tiêu đề.
bsd
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.