2012-07-03 32 views
7

Tôi cố gắng để sắp xếp một danh sách tên tiếp theo một chuỗi khác như:Cách sắp xếp với nhiều dòng trong bash?

John Doe 
AVAIL 

Sara Doe 
CALL 

Jim Doe 
AVAIL 

Tôi cố gắng để sắp xếp này bằng tên nhưng dường như không thể hình dung nó ra với phân loại. Ai đó có thể cung cấp một số hướng dẫn?

đầu ra cuối cùng của tôi sẽ trông như thế này:

Jim Doe 
AVAIL 

John Doe 
AVAIL 

Sara Doe 
CALL 

nhiều đánh giá cao!

+0

Điều thú vị là từ ví dụ của bạn, nó không rõ ràng cho dù bạn sắp xếp đối với người đầu tiên hoặc dòng thứ hai với;) –

+0

Xin lỗi tôi thực sự muốn để sắp xếp theo thứ tự chữ cái cho dòng đầu tiên. –

Trả lời

6

lẽ xa tối ưu, nhưng

sed -r ':r;/(^|\n)$/!{$!{N;br}};s/\n/\v/g' names | sort | sed 's/\v/\n/g' 

dường như thực hiện công việc (names là file với hồ sơ). Điều này cho phép các bản ghi có chiều dài tùy ý, không chỉ 2 dòng.

+0

Nó chắc chắn làm việc cho mục đích của tôi. –

+1

@lev cho những người không khá "thông thạo" trong "sed' bạn có thể đưa ra một đoạn tường thuật ngắn về phần đầu tiên của biểu thức không? Cách tiếp cận cơ bản của bạn có loại bỏ các dòng mới (đặt '\ v'? Vào vị trí của nó), sắp xếp một dòng dài, và sau đó thay thế' \ v' cho '\ n'? – Levon

+0

@Levon Bạn hoàn toàn đúng :) Nó đọc tất cả mọi thứ lên đến một dòng trống (một bản ghi), sau đó thay đổi dòng mới trong nó thành '\ v'. Bây giờ tất cả các bản ghi trên các dòng đơn. Chúng được sắp xếp, sau đó '\ v' được chuyển đổi thành' \ n'. –

0

Bạn không chắc chắn liệu nó có hiệu quả với bạn hay không nhưng với một số hạn chế ở đây là một dòng thực hiện những gì bạn cần.

awk '{if ((NR%2-1)==0) {line=sprintf("%-30s",$0)} else {print line ":" $0}}' | \ 
    sort --key=1,30 | tr ':' '\n' 

Giả định: Không có dòng trống giữa các bản ghi, tên luôn nhỏ hơn 30 ký tự và không có : được sử dụng trong văn bản.

Tôi chắc chắn bạn có thể tìm cách thay đổi nó nếu các giả định khác nhau.

Tóm lại, hợp nhất hai dòng bằng cách sử dụng dấu ':' làm dấu phân tách, các dải đầu tiên có 30 ký tự và sắp xếp bằng 30 ký tự đầu tiên. Sau đó, nó phá vỡ dòng trở lại.

0

không trực tiếp, nhưng bạn có thể sử dụng một số biểu mẫu trung gian như thế này. tôi giả sử rằng giá trị của bạn (CALL, AVAIL, v.v.) bị giới hạn. nếu không bạn cần phải sử dụng các mẫu phức tạp hơn, nhưng nó có thể được thực hiện. thực sự bất cứ điều gì có thể được thực hiện trong bash :-)

cat sorting | sed -n '1h; 1!H; ${ g; s/\nCALL\n/::CALL::/g; s/\nAVAIL\n/::AVAIL::/g ; s/\nAVAIL/::AVAIL::/g p }' | sort | sed "s/::/\n/g" 
Jim Doe 
AVAIL 

John Doe 
AVAIL 

Sara Doe 
CALL 
Các vấn đề liên quan