linux下文件大小排序 hdfs文件系统中的文件大小排序
前言
在工作和学习中,我们经常需要做一些简单的运维工作,其中最为典型的就是磁盘空间管理。这其中用到最多的就是获取文件占用的空间,并进行排序。
针对本地磁盘文件的排序很简单,但是针对hdfs文件需要借助一些shell命令进行辅助处理。
一、本地磁盘文件排序
1. sort常用参数
SYNOPSIS
du [OPTION]... [FILE]...
OPTION
-a, --all 默认只显示文件夹,加此参数会显示文件
-d, --max-depth=N 默认展示层级为最深层的文件夹,此参数可控制层级
-h, --human-readable 将size换算成更为人性化的方式
--si 类似 -h, but use powers of 1000 not 1024 (换算比例差异)
-k 等价 --block-size=1K
-b, --bytes 等价 --apparent-size --block-size=1
-m 等价 --block-size=1M
-B, --block-size=SIZE (SIZE的可选值如下)
SIZE
K, M, G, T, P, E, Z, Y (powers of 1024)
or
KB, MB, ... (powers of 1000)
2. 只取当前层级文件夹和文件的大小,单位进行人性化展示
# 当前目录的目录树
$ tree
.
├── coordinator.xml
├── coor.log
├── gen_action.sh
├── hive-exec-3.1.0.3.1.4.0-315.jar
├── job.properties
├── oozie_1
│ ├── getDate.sh
│ ├── job.properties
│ ├── mr_1.sh
│ └── workflow.xml
├── oozie_2
│ ├── getDate.sh
│ ├── job.properties
│ ├── mr_2.sh
│ └── workflow.xml
├── test_ads
│ ├── 1
│ │ ├── 1_1.sh
│ │ ├── 1_2.sh
│ │ └── 1_3.sh
│ ├── 2
│ │ ├── 2_1.sh
│ │ ├── 2_2.sh
│ │ └── 2_3.sh
│ ├── 3
│ │ ├── 3_1.sh
│ │ ├── 3_2.sh
│ │ └── 3_3.sh
│ └── workflow.xml
└── workflow.xml
# 根据要求查看size 目录只取1级
$ du -a -h -d 1
20K ./oozie_1
4.0K ./workflow.xml
4.0K ./gen_action.sh
4.0K ./job.properties
20K ./oozie_2
492K ./coor.log
41M ./hive-exec-3.1.0.3.1.4.0-315.jar
32K ./test_ads
4.0K ./coordinator.xml
42M .
3. 几种不同的排序
# -n 数值类型排序 -r 指定为倒序 -k 指定排序字段坐在的列
$ du -a -d 1 | sort -nrk1
42016 .
41432 ./hive-exec-3.1.0.3.1.4.0-315.jar
492 ./coor.log
32 ./test_ads
20 ./oozie_2
20 ./oozie_1
4 ./workflow.xml
4 ./job.properties
4 ./gen_action.sh
4 ./coordinator.xml
# 如du指定了-h,进行排序时需将-n改为-h
$ du -a -h -d 1 | sort -hrk1
42M .
41M ./hive-exec-3.1.0.3.1.4.0-315.jar
492K ./coor.log
32K ./test_ads
20K ./oozie_2
20K ./oozie_1
4.0K ./workflow.xml
4.0K ./job.properties
4.0K ./gen_action.sh
4.0K ./coordinator.xml
二、hdfs文件排序
1. sed高级匹配
$ echo aaa111bbb222 | sed 's/\([a-z]*\)\([0-9]*\)\(.*\)/\2/g'
111
$ echo aaa111bbb222 | sed 's/\([a-z]*\)\([0-9]*\)\(.*\)/\1\3/g'
aaabbb222
# 's/\([a-z]*\)\([0-9]*\)\(.*\)/\2/g' 实际对应 's/([a-z]*)([0-9]*)(.*)/\2/g',因实操中发现()和{}必须使用\进行转义,建议先按照更为直观的后者的模式书写正则,然后加转义字符改成前者这种正确的语法。
# 此正则的含义为依次匹配连续字母、连续数字和任意字符,每个()作为一个匹配组,依次与后面的\1、\2、\3...对应
# 可单独取出匹配组如\1;取出多个匹配组\1\3或者\3\2;取出时可加入其他字符hello\1world\3。
2. 获取hdfs加目录文件列表
# 此处过滤掉了大小为0的文件
$ hadoop fs -du -h | egrep -v '^0'
40.5 M 80.9 M .hiveJars
1.8 G 3.6 G .sparkStaging
1.8 G 17.8 G .staging
685.6 K 1.3 M .test
etc...
2. 通过pipline直接调用本地的sort方法
# 正常倒序输出,结果显然不对
$ hadoop fs -du -h | egrep -v '^0' | sort -rk1 | head -5
97.0 K 194.0 K t_clerk_main
685.6 K 1.3 M .test
6.7 G 13.5 G OozieApps
620.5 M 1.2 G commonLibs
5.4 K 10.9 K t_clerk_terminal
# 加-n指定为数值类型排序,仍不是想要的结果
$ hadoop fs -du -h | egrep -v '^0' | sort -nrk1 | head -5
685.6 K 1.3 M .test
620.5 M 1.2 G commonLibs
335.6 M 671.3 M data
213.2 K 426.3 K oozie-oozi
175.1 M 350.2 M dicts
# 加-h参数表示我们使用了任性话单位,结果同上
$ hadoop fs -du -h | egrep -v '^0' | sort -hrk1 | head -5
685.6 K 1.3 M .test
620.5 M 1.2 G commonLibs
335.6 M 671.3 M data
213.2 K 426.3 K oozie-oozi
175.1 M 350.2 M dicts
我们发现上面-n和-h输出的结果完全一致,但是产生的结果为何和本文第一部分本地文件调用sort不同呢?
经过对比发现,hdfs fs -du输出size信息中数字和单位间存在空格,所以sort -k1其实只取了数字那一列 …
3. 使用sed删除size信息中数值和单位间的空格
# \2即为空格 直接取\1\3即可~
$ hadoop fs -du -h | egrep -v '^0' | sed 's/\([0-9.]\)\( \)\(.*\)/\1\3/g' | sort -rhk1
6.7G 13.5 G OozieApps
1.8G 3.6 G .sparkStaging
1.8G 17.8 G .staging
620.5M 1.2 G commonLibs
335.6M 671.3 M data
175.1M 350.2 M dicts
116.9M 233.9 M sql-to-json-udf-1.0-SNAPSHOT.jar
40.5M 80.9 M .hiveJars
10.9M 21.8 M ***_055_20210806.txt
2.8M 5.5 M tmp
685.6K 1.3 M .test
总结
shell中很多命令功能强大,多数可支持正则并实现很多不可思议的功能,期待和大家一起在工作和学习中慢慢琢磨和实践。