Làm thế nào để có được n dòng cho mỗi m dòng (n <m) trong dòng lệnh?


7

Có một cách rất đơn giản (có thể sử dụng một dòng với sed?) Để có được ncác dòng, bắt đầu từ dòng ath trong đoạn nđường này, cho mỗi mdòng?

Cụ thể hơn, tôi có một tập tin với hàng triệu dòng. Cứ 4 dòng, tôi muốn có hai dòng đầu tiên.

Nhưng tôi đoán tôi cũng muốn có một ý tưởng để làm điều này trong các tình huống tương tự khác. Đó là lý do tại sao tôi hỏi một câu hỏi tổng quát hơn ở đây.


4
Vui lòng chỉnh sửa câu hỏi cho rõ ràng.
mkc

1
Ý bạn là sed '1~3,+1 ! d' file_with_million_linessao
Costas

Bạn cũng có thể muốn xem xét Awk - GNU sed có chế độ địa chỉ đẹp cho việc này, nhưng nó không khả dụng.
Toby Speight

Câu trả lời:


12

Với gnu split:

n=2
m=4 
split -l ${m} --filter="head -n ${n}" infile

và nếu bạn muốn làm điều đó chỉ sau idòng thứ, chỉ cần chuyển hướng các dòng trước đó sang /dev/null:

n=2
m=4 
i=7
{ head -n ${i} >/dev/null; split -l ${m} --filter="head -n ${n}"; } <infile

Nếu bạn không có quyền truy cập vào gnucác công cụ bạn có thể sử dụng awk:

awk -vn=2 -vm=4 -vi=7 'NR<=i{next}; (NR-i)%m==1{c=1}; c++<=n' infile

Điều này giải quyết vấn đề chung hơn cho tôi. Cảm ơn bạn.
cà phê

2
Đơn giản hơn:'NR<=i{next} c++%m<n'
dave_thndry_085

15

Bạn có thể sử dụng ~địa chỉ trong GNU sed:

sed -n '1~4p;2~4p'

Trong đó có dòng chữ "In dòng đầu tiên cứ sau 4 dòng và in dòng thứ hai cứ sau 4 dòng" hoặc "Bắt đầu từ dòng 1, in mỗi dòng thứ 4 và bắt đầu từ dòng 2, in mỗi dòng thứ 4".


5

Đối với GNU sed

sed '3~4,+1 d' file

hoặc tổng quát hơn:

m=4
n=2
sed "$((m-n+1))~$m,+$((m-n-1)) d" file

4

Hoặc này , gnu sed:

sed -n -e '1~4 {N; p;}' file

-nthay thế đầu ra. Nếu tại dòng 1+4*k(k = iterator) thì dòng hiện tại và dòng tiếp theo được đọc vào pattern spacepin không gian mẫu (hiện tại) (tức là cho phép đầu ra tạm thời)

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.