2012-07-28 22 views
8

Tôi có tệp đầu vào trông như thế này (cột đầu tiên là số vị trí và số thứ hai là số cần tăng theo thời gian) :giải pháp awk để so sánh dòng hiện tại với dòng tiếp theo và in một trong các dòng dựa trên điều kiện

1  0 
1  2 
1  6 
1  7 
1  7 
1  8 
1  7 
1  7 
1  9 
1  9 
1  10 
1  10 
1  9 
1  10 
1  10 
1  10 
1  10 
1  10 
1  10 
1  9 
1  10 
1  10 
1  10 
1  10 
1  10 
1  10 

và tôi muốn sửa chữa nó trông như thế này (đếm thay thế mà giảm với số lượng trước):

1  0 
1  2 
1  6 
1  7 
1  7 
1  8 
1  8 
1  8 
1  9 
1  9 
1  10 
1  10 
1  10 
1  10 
1  10 
1  10 
1  10 
1  10 
1  10 
1  10 
1  10 
1  10 
1  10 
1  10 
1  10 
1  10 

tôi đã cố gắng sử dụng awk cho điều này, nhưng tôi stumbling với getline kể từ khi tôi không thể có vẻ để tìm ra cách để thiết lập lại số dòng (NR?) vì vậy nó sẽ r ead mỗi dòng và đó là dòng tiếp theo, không phải hai dòng tại một thời điểm. Đây là mã tôi có cho đến nay, bất kỳ ý tưởng?

awk '{a=$1; b=$2; getline; c=$1; d=$2; if (a==c && b<=d) print a"\t"b; else print c"\t"d}' original.txt > fixed.txt 

Ngoài ra, đây là sản phẩm Tôi hiện đang nhận được:

1  0 
1  6 
1  7 
1  7 
1  9 
1  10 
1  9 
1  10 
1  10 
1  9 
1  10 
1  10 
1  10 
+0

Ok, chỉ cần làm rõ, bạn đang cố gắng * bỏ qua * các dòng mà số lượng giảm? Đó là rất nhiều dòng, tôi tự hỏi nếu bạn có thể đưa ra một ví dụ ngắn hơn mà sẽ được chỉ là rõ ràng? – Levon

+0

Xin lỗi nếu lời giải thích của tôi không rõ ràng, tôi muốn in dòng trước khi số đếm giảm, vì vậy kết thúc với cùng số dòng nhưng với một tệp mà số đếm đặt hoặc tăng, nhưng không bao giờ giảm. – suegene

+0

Tôi hiểu rồi .. hãy xem các câu trả lời được cung cấp bên dưới, tôi nghĩ bạn sẽ tìm thấy những gì bạn đang tìm kiếm. – Levon

Trả lời

7

Có lẽ tất cả các bạn muốn là:

awk '$2 < p { $2 = p } { p = $2 } 1' input-file 

này sẽ thất bại trên dòng đầu tiên nếu giá trị trong cột thứ hai là số âm, do đó:

awk 'NR > 1 && $2 < p ...' 

Điều này đơn giản đặt cột thứ hai thành giá trị trước đó nếu giá trị hiện tại nhỏ hơn, sau đó lưu trữ giá trị hiện tại trong biến p, sau đó in dòng.

Lưu ý rằng điều này cũng hơi sửa đổi khoảng cách của đầu ra trên các dòng thay đổi. Nếu đầu vào của bạn được chia tách bằng tab, bạn có thể muốn làm:

awk 'NR > 1 && $2 < p { $2 = p } { p = $2 } 1' OFS=\\t input-file 
+0

Wow .. nhiều hơn nữa ngắn gọn .. Tôi nghĩ rằng tôi có phiên bản tiết của giải pháp đầu tiên của bạn – Levon

+0

Tuyệt vời, tôi chỉ cố gắng tìm ra khoảng cách, cảm ơn! – suegene

2

Kịch bản này sẽ làm những gì bạn thích:

{ 
    if ($2 < prev_count) 
    $2 = prev_count 
    else 
    prev_count = $2 

    printf("%d %d\n", $1, $2) 
} 

Đây là phiên bản tiết được dễ dàng đọc được :)

+0

Cảm ơn, tôi cũng đánh giá cao phiên bản tiết lộ! – suegene

+0

@suegene Vui lòng trợ giúp .. Tôi đã điều chỉnh khoảng cách đầu ra bằng 'printf' có thể cho phép bạn kiểm soát tốt hơn một chút so với định dạng/khoảng cách nếu bạn cần. – Levon

Các vấn đề liên quan