Sắp xếp các dòng theo số lượng từ trên mỗi dòng


14

Đưa ra đầu vào:

hello: world foo bar baz
bar:
baz: bin boop bop fiz bang beep
bap: bim bam bop
boatkeeper: poughkeepsie

Tôi muốn sắp xếp nó thành hầu hết các từ ở đầu, ít nhất là ở cuối, như vậy:

baz: bin boop bop fiz bang beep
hello: world foo bar baz
bap: bim bam bop
boatkeeper: poughkeepsie
bar:

Làm thế nào tôi có thể làm điều này với sorthoặc một số công cụ khác?


Để rõ ràng, bạn muốn sắp xếp theo số lượng từ không sắp xếp theo độ dài dòng (với mẫu đầu vào của bạn, dòng có nhiều từ nhất cũng dài nhất nhưng điều đó có thể không phải luôn luôn như vậy)?
don_crissti

Đúng. Dòng có nhiều từ nhất không nhất thiết phải dài nhất nói chung. ví dụ như tôi muốn bin: bop booptrước boatkeeper: poughkeepsie. Nếu hai dòng chia sẻ cùng một số từ, tôi muốn các mối quan hệ được sắp xếp theo thứ tự chữ cái, nhưng đó không phải là một yêu cầu.
Caleb Xu

Câu trả lời:


22

Bạn có thể làm một cái gì đó như:

awk '{print NF,$0}' file | sort -nr | cut -d' ' -f 2-

Chúng tôi sử dụng awkđể tiền tố số lượng các trường cho mỗi dòng. Chúng tôi sau đó sortbằng số đó và loại bỏ nó với cut.


Điều này đã làm việc. Đã tự hỏi tại sao thứ tự bị đảo ngược, nhưng tôi thấy chỉnh sửa của bạn bây giờ.
Caleb Xu

6

Trong GNU gần đây, awkngười ta có thể sử dụng PROCINFOmảng để xác định nhiều tham số bên trong bao gồm cả thứ tự in các phần tử mảng (được điều khiển bởi phần tử "sorted_in"). Do đó, chúng ta có thể xây dựng và lập chỉ mục mảng với giá trị của NF" "NR, phần tử nào có giá trị $0và in nó trong đầu ra mong muốn, trong trường hợp của bạn sẽ là "@ind_num_desc":

awk '{a[NF" "NR]=$0}END{PROCINFO["sorted_in"]="@ind_num_desc"; for(i in a) print a[i]}' file

1
+1 đã nghĩ giống như vậy: tuy nhiên người ta có thể lưu ý rằng nó sẽ có tác dụng phụ là sao chép lại đầu vào
Steeldo

@steel ấn bạn hoàn toàn chính xác, tôi đã chỉnh sửa câu trả lời của mình, bây giờ sẽ ổn thôi.
jimmij

Điều này hiện duy trì thứ tự ban đầu giữa các bản ghi có cùng số trường, thay vì sắp xếp các từ dưới dạng khóa sắp xếp thứ cấp. Nếu khóa của bạn là NF" "$0" "NR, bạn chỉ có NRcơ chế xử lý dự phòng / sao chép.
Peter Cordes

1
@PeterCordes nhưng điều đó sẽ đảo ngược thứ tự các từ, tôi thấy không có cách nào để giải quyết các mối quan hệ theo thứ tự chữ cái khác mà theo định nghĩa hàm riêng cmp_func()- gnu awk cho phép điều đó.
jimmij

5

Perl một lớp lót:

print sort { split(' ',$a) <=> split(' ',$b) } <>;

Nếu bạn muốn phá vỡ mối quan hệ bằng cách sử dụng thứ tự bảng chữ cái:

print sort { split(' ',$a) <=> split(' ',$b) or $a cmp $b } <>;

4

Qua trăn.

s = '''hello: world foo bar baz
bar:
baz: bin boop bop fiz bang beep
bap: bim bam bop'''.splitlines()
for i in sorted(s, key=lambda x: len(x.split()), reverse=True):
    print(i)

hoặc là

with open('/path/to/the/input/file') as f:
    m = f.readlines()
    for i in sorted(m, key=lambda x: len(x.split()), reverse=True):
        print(i, end="")
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.