Сортуйте рядки за кількістю слів на рядок


14

Даний вклад:

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

Я хотів би відсортувати його у більшості слів у верхній частині, принаймні в кінці, як-от так:

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

Як би я це зробив за допомогою sortчи іншого інструменту?


Щоб було зрозуміло, ви хочете сортувати за кількістю слів, не впорядкованими за довжиною рядка (при введенні зразка рядок із більшою кількістю слів також є найдовшим, але це не завжди може бути)?
don_crissti

Так. Рядок з найбільшою кількістю слів не обов’язково найдовший загалом. наприклад, я хочу bin: bop boopраніше boatkeeper: poughkeepsie. Якщо два рядки мають однакову кількість слів, я вважаю за краще, щоб зв’язки були в алфавітному порядку, але це не є вимогою.
Калеб Сю

Відповіді:


22

Ви можете зробити щось на кшталт:

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

Ми використовуємо awkдля приставки кількість полів до кожного рядка. Потім ми sortза цим номером і видаляємо його cut.


Це спрацювало. Мені було цікаво, чому замовлення було скасовано, але я бачу вашу редакцію зараз.
Калеб Сю

6

В останній GNU awkможна використовувати PROCINFOмасив для визначення багатьох внутрішніх параметрів, включаючи порядок друку елементів масиву (керованих елементом "sorted_in"). Таким чином, ми можемо побудувати та масив, індексований значенням NF" "NR, елементи якого мають значення $0та надрукувати його на потрібному виході, у вашому випадку це буде "@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 думав те саме: проте, можливо, слід зазначити, що це буде побічним ефектом
дедублювання

@steeldriver Ви абсолютно правильні, я відредагував свою відповідь, зараз має бути добре.
jimmij

Тепер це зберігає оригінальне впорядкування між записами з однаковою кількістю полів, а не сортування за словами як вторинний ключ сортування. Якби ваші ключі були NF" "$0" "NR, ви мали би лише NRмеханізм резервного копіювання / обробки дублікатів.
Пітер Кордес

1
@PeterCordes, але це змінило б порядок слів, я не бачу способу вирішити зв'язки в алфавітному порядку, що за визначенням власна функція cmp_func()- gnu awk дозволяє це.
jimmij

5

Perl однолінійний:

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

Якщо ви хочете розірвати зв’язки за алфавітом:

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

4

Через пітон.

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)

або

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="")
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.