Як сортувати людський читабельний розмір


11

Я в основному шукаю файли, а потім сортую за розміром. Сценарій працює, якщо я не сортую розмір за людським читанням. Але я хочу, щоб розмір був читабельним для людини. Як можна сортувати розміри, які читаються людиною?

Наприклад:

 ls -l | sort -k 5 -n | awk '{print $9 " " $5}'

Це працює, як очікувалося, розмір моїх файлів у байтах зростає:

1.txt 1
test.txt 3
bash.sh* 573
DocGeneration.txt 1131
andres_stuff.txt 1465
Branches.xlsx 15087
foo 23735
bar 60566
2016_stuff.pdf 996850

Тепер я хочу, щоб розмір був читабельним для людини, тому я додав параметр -h до ls, і тепер деякі файли вийшли з ладу:

 ls -lh | sort -k 5 -n | awk '{print $9 " " $5}'
1.txt 1
DocGeneration.txt 1.2K
andres_stuff.txt 1.5K
test.txt 3
Branches.xlsx 15K
foo 24K
bar 60K
bash.sh* 573
2016_stuff.pdf 974K


-k 5- як це працює?
ctrl-alt-delor

@ ctrl-alt-delor: Я вважаю, що розмір знаходиться у 5-му стовпці lsрезультату
jesse_b

2
Використання duзамість lsможе бути хорошою ідеєю.
ксеноїд

... або find's -printfз його %pта %sформатерами (з подальшим «гуманізацією» розмірів).
Стівен Кітт

@Jesse_b моя помилка, я просто припустив, що дані у питанні (позначені як це те, що я отримав) були відсортованими введеннями. Я помилявся.
ctrl-alt-delor

Відповіді:


28

Спробуйте sort -h k2

-h, - людське числове порівняння порівняти читані людиною цифри (наприклад, 2K 1G)

Вона входить до сорту gnu, сорту BSD та інших.


5
Чи не lsслід уникати розбору результатів ?

3
@Tomasz Не завжди. Якщо він надає потрібний вам вихід, передача його на іншу операцію форматування не є особливо небезпечною. Те, що ви не повинні робити, - це петля над висновком ls, а замість цього використовувати безпосередньо глобулювання файлів. Глобінг поодинці тут не працюватиме. Це сказало, що я, мабуть, вважаю duза краще це.
Кривавий виїзд

1
@Bloodgain формат ls не гарантується однаковим для систем / бінарних файлів, тому аналіз його портативно вважається неможливим.
D. Ben Knoble

1
Також назви файлів із пробілами будуть заплутувати речі
D. Ben Knoble,

1
@Bloodgain: files=(); for f in *; do [[ -L "$f" ]] && files+=("$f"); done; echo ${#files[@]}(Можливо, у мене неправильний тестовий перемикач симпосилання ). Якщо вам не байдуже символьні посилання, files=(*); echo ${#files[@]}які стають портативними, якщо ви використовуєте, setа не масиви.
D. Ben Knoble

29

lsвбудована ця функціональність, використовуйте -Sпараметр і сортуйте у зворотному порядку:ls -lShr

       -r, --reverse
              reverse order while sorting

       -S     sort by file size, largest first

1
-hне є стандартним lsваріантом , але він повинен бути корисним, якщо в ОП вже є. Решта стандартні, і це, безумовно, відповідь, яку я написав би.
Toby Speight

5
+1 Не плутайте навколо аналізу результатів ls.
Девід Річербі

Це найкраща відповідь, але вона повинна містити інформацію в коментарі @ Toby: -Sможе бути недоступною для ваших ls. FWIW, -Sпідтримується навіть з бібліотекою Emacs ls-lisp.el, яка використовується, коли в ОС немає ls. Наприклад, він працює в Emacs на MS Windows.
Дрю

Це має бути прийнятою відповіддю.
розкидання

1
@Drew: У коментарі Тобі написано, що це -hможе не бути повсюдно доступним, але ОП це все одно використовує. -Sнасправді має бути загальнодоступним, оскільки це знаходиться у позі POSIX, яке надає Toby. Однак там існує чимало наборів інструментів, які не є POSIX.
Кевін

5

Оскільки жодної конкретної оболонки не було згадано, ось як це зробити в zshоболонці:

ls -lhf **/*(.Lk-1024oL)

**Модель Глоба відповідає як , *але через /в імені шляху, тобто як би рекурсивний пошук.

lsКоманда дозволить читаним розміри людини з -h, а вихідний формат довгий список з -l. Цей -fпараметр вимикає сортування, тому lsпросто перелічіть файли в тому порядку, в якому вони задані.

Цей порядок впорядкований по **/*(.Lk-1024oL)шаблону імені файлів, таким чином, щоб перші файли були перелічені нижче. **/*Біт відповідає кожен файл і каталог в цьому каталозі і нижче, але (...)модифікує поведінку Глоб ( в це «Глоб класифікатор»).

Це oLв кінці, що упорядковує ( o) імена за розміром файлу ( L, "довжина").

На .початку вказує, що глобул відповідає лише звичайним файлам (без каталогів).

У Lk-1024біт вибирає файли, розмір яких становить менше 1024 Кб ( «довжина в КБ менш ніж 1024»).

Якщо zshце не ваша основна інтерактивна оболонка, ви можете використовувати її

zsh -c 'ls -lf **/*(.Lk-1024oL)'

Використовуйте setopt GLOB_DOTS(або zsh -o GLOB_DOTS -c ...), щоб також відповідати прихованим іменам. ... або просто додати Dдо рядка глобального класифікатора.


Розширюючи вищесказане, припускаючи, що ви хочете вивести двоколонний вихід з іменами шляхів і зручними для читання розмірами, а також припустивши, що ви маєте numfmtGNU coreutils,

zmodload -F zsh/stat b:zstat

for pathname in **/*(.Lk-1024oL); do
    printf '%s\t%s\n' "$pathname" "$(zstat +size "$pathname" | numfmt --to=iec)"
done

або, швидше,

paste <( printf '%s\n' **/*(.Lk-1024oL) ) \
      <( zstat -N +size **/*(.Lk-1024oL) | numfmt --to=iec )

4

Якщо у вас sortнемає -hможливості, ви можете використовувати (хоч і дуже довгу) команду awk на зразок наступного:

find . -type f -size -1024k -exec ls -al {} \; | sort -k 5 -n | awk '{if ($5 > 1099511627776) {print $9,$5/1024/1024/1024/1024"T"} else if ($5 > 1073741824) {print $9,$5/1024/1024/1024"G"} else if ($5 > 1048576) {print $9,$5/1024/1024"M"} else if ($5 > 1024) {print $9,$5/1024"K"} else {print $9,$5"B"}}' | column -t

Це відсортує ваш вихід у байтах, а потім перетворить їх на їх людський читабельний розмір.


-1

Це працювало б?

ls -l | awk '{if ($5<=1024) {print}}' | sort -k 5 -n | awk '{print $9"\t"substr($5/1024,1,3)"k"} '| column -t

Перший awkдосвід буде шукати файли менше 1 М, а другий буде приймати розмір байту з результату і перетворювати його в КБ та друкує перші 3 елементи для отримання зручного для читання розміру.


Це насправді не вирішує питання про оперативні програми - воно виглядає лише у поточному каталозі та друкуватиме лише звичайні файли. Також порівняємо проти 1 Кб замість 1 МБ. Нарешті, ми отримуємо відповіді з деякими поясненнями, чому працює код.
grochmal

Мій поганий додав, що це робить.
Виньєш СП
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.