一段文件相关的shell脚本解读

简介: CODE: #!/sbin/ksh dir=${1:-.} (cd $dir;pwd) find $dir -type d -print | du | awk '{print $2, "== ("$1/2"kb)"}' |sort -f | sed ...
CODE:
#!/sbin/ksh
dir=${1:-.}
(cd $dir;pwd)
find $dir -type d -print | du | awk '{print $2, "== ("$1/2"kb)"}' |sort -f |
sed -e "s,[^ /]*/\([^ /]*\) ==,\|--\1," -e"s,[^ /]*/,| ,g"
#The End

感觉有些难度,不知哪位大侠能够给在下解释一下!
作者: feeling    时间: 2002-3-21 20:59     标题: Shell的魅力

第五行是紧跟在第四行之后的,由于太长被强制换行了。
作者: michaelds    时间: 2002-3-21 21:55     标题: Shell的魅力

[这个贴子最后由michaelds在 2002/03/21 10:06pm 编辑]

这个程序包含的知识点比较多,如果不是在这些点方面均有了解的话,理解起来会比较困难。但是仔细分析搞懂,还是很有收获的。因此在这里细细解读一下:
程序目的:
对指定的目录,显示该目录及其下所有子目录所占用的空间。显示方式上,要求以类windows树状结构的方式表现目录和子目录的关系,显示空间大小用(?kb)的样式说明。
程序代码:
(1)#!/sbin/ksh
(2)dir=${1:-.}
(3)(cd $dir;pwd)
(4)find $dir -type d -print | du | awk '{print $2, "== ("$1/2"kb)"}' |sort -f | sed -e "s,[^ /]*/\([^ /]*\) ==,\|--\1," -e"s,[^ /]*/,| ,g"

(1)表明使用的shell解释器为ksh
(2)对变量dir赋值,如果执行该程序时指定了第一参数$1,那么dir的值即为$1(即指定目录),如果没有指定参数,那么dir的值为"."(即当前目录)。这种变量设置的模式还有=value、+value、:?value、?value、:=value、:-value,各有其功能。
(3)为了首先显示一下处理的路径所在的主目录,需要进至该目录,然后用pwd命令显示出来。用()括起来,表示这两句作为一组命令一起执行,而且有个重要的好处就是执行完后不会影响程序的当前路径,可以理解是()使其内部命令在一子shell中运行,一旦执行完毕便恢复原shell的环境。
(4)这句是关键。
首先find $dir -type d -print表明要把$dir指定的目录下所有的子目录都找到并显示出来。-type d说明找的是目录而不是文件。
然后,使用du命令显示每一目录所占空间由于du命令显示的单位是512字节块,因此要将得到的值除以2,得到kb值。根据du的输出结果,第二列是目录,第一列是值,因此使用awk分别处理,$1/2的表达式要用引号引起是要让awk正确识别表达式。
sort -f是要把输出的结果排序,按字母顺序排序,便于使用的人察看。使用-f可以让sh排序时对大小写不敏感。
sed一句是关键中的关键,-e的写法可以使sed连续执行多套命令,此处有两个-e。来看命令集:s打头,表明了是一个替换任务,跟我们熟悉的不同,我们平时用s/aa/bb/这样的形式较多,但对于sed来说,分隔符是可以自行任意指定的,这里sed将跟在s命令后的","作为了分隔符。于是就有了s,...,...,的样子。
我们知道格式是“s/源串/目标串/”,那么第一组命令,源串是说什么呢?[]的用法在sed中表示:取[]字符组中的一个字符,而[]中的第一位若是"^",则表示不取后面的任何一个字符。那么[^ /]*/就表示匹配这样的格式:"由不是空格或/的一个或多个字符组成的串,后面紧跟一个/",接下来有\(......\)的格式,这种格式用在源串中,表示用这种符号括注的部分要sed记住,而且sed会给这个部分自动起个名字叫\1,如果在源串中还有这样的标记,就依次命名为\2,\3......。这\1要sed记住什么呢?是"[^ /]*",这还是说"由不是空格或/的一个或多个字符组成的串"。\1之后还有" =="也是源串中要求匹配的。再来看目标串,就是要替换成的串,是"\|--\1",作者认为"|"是特殊字符,所以前跟\号(其实不必)。"--"是普通符号了,\1就是我们刚才在源串中要求标记的部分,换到这里来。
第二组命令简单一些。源串:"[^ /]*/",仍然是"由不是空格或/的一个或多个字符组成的串,后面紧跟一个/",目标串是"| ",最后一个g表明全行替换,就是说如果在一行中有多处匹配源串,都要替换成目标串。
再从该程序应用的角度看这一句的功能:
作者是要把这样的显示结果
. == (904724kb)
./bak == (1kb)
./billfile == (1kb)
./bin == (11646kb)
./bin/images == (16kb)
....................
替换成这样的结果
. == (904724kb)
|--bak (1kb)
|--billfile (1kb)
|--bin (11646kb)
| |--images (16kb)
....................
对于"aaa/xxxx/yyyy =="分解这一要求,实际是两步,先把"xxxx/yyyy =="替换为"|--yyyy",然后将aaa变成"| "(如没有aaa则无行为),在aaa中含有几个/,就换成几个"| "。这里的sed命令恰好完成了这一功能。

程序改进:
(1)实际该程序没有使用ksh的任何特殊功能,改为sh仍可正常运行,兼容性会更好。
(2)先find再du是没有必要的。因为du本身就能寻找子目录,且自动显示每个子目录的大小。另外,如果对指定的目录无读权限的话,find就会报出错,但直接用du则没事。
(3)"|"在sed中不是特殊字符不必再用"\"转义了。
最后我的建议结果如下:
#!/bin/sh
dir=${1:-.}
(cd $dir;pwd)
du $dir| awk '{print $2, "== ("$1/2"kb)"}' |sort -f|sed -e "s,[^ /]*/\([^ /]*\) ==,|--\1," -e "s,[^ /]*/,| ,g"
作者: valentine    时间: 2002-3-21 23:27     标题: Shell的魅力

michaelds 解释的太好了。

我想我们大家在注意shell的时候,应该注意shell中处处用得到的正则表达式。
^,$,.,*,[] 应该很清楚,这样在sed ,awk,case,vi ...里都能顺畅自如.
目录
相关文章
|
1月前
|
Shell
Shell 文件包含
10月更文挑战第5天
33 4
|
2月前
|
Unix Shell Linux
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
本文提供了几个Linux shell脚本编程问题的解决方案,包括转置文件内容、统计词频、验证有效电话号码和提取文件的第十行,每个问题都给出了至少一种实现方法。
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
|
1月前
|
Shell
一个用于添加/删除定时任务的shell脚本
一个用于添加/删除定时任务的shell脚本
75 1
|
18天前
|
Shell Linux 测试技术
6种方法打造出色的Shell脚本
6种方法打造出色的Shell脚本
42 2
6种方法打造出色的Shell脚本
|
4天前
|
XML JSON 监控
Shell脚本要点和难点以及具体应用和优缺点介绍
Shell脚本在系统管理和自动化任务中扮演着重要角色。尽管存在调试困难、可读性差等问题,但其简洁高效、易于学习和强大的功能使其在许多场景中不可或缺。通过掌握Shell脚本的基本语法、常用命令和函数,并了解其优缺点,开发者可以编写出高效的脚本来完成各种任务,提高工作效率。希望本文能为您在Shell脚本编写和应用中提供有价值的参考和指导。
14 1
|
9天前
|
Ubuntu Shell 开发工具
ubuntu/debian shell 脚本自动配置 gitea git 仓库
这是一个自动配置 Gitea Git 仓库的 Shell 脚本,支持 Ubuntu 20+ 和 Debian 12+ 系统。脚本会创建必要的目录、下载并安装 Gitea,创建 Gitea 用户和服务,确保 Gitea 在系统启动时自动运行。用户可以选择从官方或小绿叶技术博客下载安装包。
24 2
|
23天前
|
监控 网络协议 Shell
ip和ip网段攻击拦截系统-绿叶结界防火墙系统shell脚本
这是一个名为“小绿叶技术博客扫段攻击拦截系统”的Bash脚本,用于监控和拦截TCP攻击。通过抓取网络数据包监控可疑IP,并利用iptables和firewalld防火墙规则对这些IP进行拦截。同时,该系统能够查询数据库中的白名单,确保合法IP不受影响。此外,它还具备日志记录功能,以便于后续分析和审计。
43 6
|
19天前
|
运维 监控 Shell
深入理解Linux系统下的Shell脚本编程
【10月更文挑战第24天】本文将深入浅出地介绍Linux系统中Shell脚本的基础知识和实用技巧,帮助读者从零开始学习编写Shell脚本。通过本文的学习,你将能够掌握Shell脚本的基本语法、变量使用、流程控制以及函数定义等核心概念,并学会如何将这些知识应用于实际问题解决中。文章还将展示几个实用的Shell脚本例子,以加深对知识点的理解和应用。无论你是运维人员还是软件开发者,这篇文章都将为你提供强大的Linux自动化工具。
|
1月前
|
监控 Unix Shell
shell脚本编程学习
【10月更文挑战第1天】shell脚本编程
66 12
|
1月前
|
存储 运维 监控
自动化运维:使用Shell脚本简化日常任务
【9月更文挑战第35天】在IT运维的日常工作中,重复性的任务往往消耗大量的时间。本文将介绍如何通过编写简单的Shell脚本来自动化这些日常任务,从而提升效率。我们将一起探索Shell脚本的基础语法,并通过实际案例展示如何应用这些知识来创建有用的自动化工具。无论你是新手还是有一定经验的运维人员,这篇文章都会为你提供新的视角和技巧,让你的工作更加轻松。
52 2