web-dev-qa-db-ja.com

人間が読めるサイズを並べ替える方法

私は基本的にファイルを探して、サイズでソートしています。このスクリプトは、人間が判読できるサイズで並べ替えない場合に機能します。しかし、私はサイズを人間が読めるようにしたいと思っています。人間が読めるサイズをどのようにソートできますか?

例えば:

 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

11
tvo000

sort -h k2をお試しください

-h、-human-numeric-sortは、人間が読み取れる数値を比較します(例:2K 1G)

これは、GNUソート、BSDソートなどの一部です。

28
ctrl-alt-delor

lsにはこの機能が組み込まれています。-Sオプションと逆順での並べ替え:ls -lShr

       -r, --reverse
              reverse order while sorting

       -S     sort by file size, largest first
29
Mark McKinstry

特定のシェルについて言及していなかったため、zshシェルですべてを行う方法は次のとおりです。

_ls -lhf **/*(.Lk-1024oL)
_

_**_ globパターンは_*_のように一致しますが、パス名の_/_全体で一致します。

lsコマンドは、_-h_で人間が読めるサイズを有効にし、_-l_で長いリスト出力フォーマットを有効にします。 _-f_オプションはソートを無効にするため、lsは指定された順序でファイルをリストするだけです。

この順序は**/*(.Lk-1024oL) filenameグロビングパターンによって配置され、小さいファイルが最初にリストされます。 _**/*_ビットは、このディレクトリ以下のすべてのファイルとディレクトリに一致しますが、_(...)_はグロブの動作を変更します(「グロブ修飾子」です)。

ファイルサイズ(oL、 "length")で名前を並べ替えるのは、最後のoです(L)。

最初に_._を使用すると、globは通常のファイルのみに一致します(ディレクトリは一致しません)。

_Lk-1024_ビットは、サイズが1024 KB未満のファイルを選択します(「KBの長さは1024未満」)。

zshがプライマリインタラクティブシェルでない場合は、

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

非表示の名前にも一致させるには、_setopt GLOB_DOTS_(または_zsh -o GLOB_DOTS -c ..._)を使用します。 ...または単にDをグロブ修飾子文字列に追加します。


上記を拡張して、パス名と人間が読めるサイズの2列の出力が必要であると想定し、さらにGNU coreutilsからのnumfmtがあると想定します。

_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 )
_
5
Kusalananda

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

これにより、出力がバイト単位で並べ替えられ、後で人間が読めるサイズに変換されます。

4
jesse_b