本章节学习一些在编写Shell时的常用命令或工具及使用技巧。有人说Shell脚本是命令堆积的一个文件,按顺序去执行。还有人说想学好Shell脚本,要把Linux上各种常见的命令或工具掌握了,这些说法都没错。由于Shell语言本身在语法结构上比较简单,是面向过程编程,想实现复杂的功能有点强人所难!而且Shell本身又工作在Linux内核之上,在用户态调用Linux命令会很方面,所以大多数情况下我们都是依靠这些命令来完成脚本中的某些功能,比如文本处理、获取系统状态等等,然后通过Shell语法结构组织代码逻辑。不管是学Linux系统好还是写Shell脚本也好,有些命令都是必须要会的,以下是根据个人经验总结的一些常用的命令。
怎么更好的学习命令呢?
当然查看官方帮助文档了,可以通过man cmd、cmd --help、help cmd、infocmd等方式查看命令的使用。
11.1 ls
功能:列出目录内容
常用选项:
-a 显示所有文件,包括隐藏的
-l 长格式列出信息
-i 显示文件inode号
-t 按修改时间排序
-r 按修改时间倒序排序
示例:
按修改时间排序: # ls -t 按修改时间倒序排序: # ls -rt 长格式列出: # ls -l 查看文件inode: # ls -i file
11.2 echo
功能:打印一行
常用选项:
-n 不加换行符
-e 解释转义符
示例:
解释换行符: # echo -e "1\n2\n3" 1 2 3
11.3 printf
功能:格式化打印数据。默认打印字符串不换行。
格式:printf format[arguments]
常用选项:
format:
%.ns 输出字符串,n是输出几个字符
%ni 输出整数,n是输出几个数字
%m.nf 输出浮点数,m是输出的整数位数,n是输出的小数位数
%x 不带正负号的十六进制值,使用a至f表示10至15
%X 不带正负号的十六进制,使用A至F表示10至15
%% 输出单个%
一些常用的空白符:
\n 换行
\r 回车
\t 水平制表符
对齐方式:
%-5s 对参数每个字段左对齐,宽度为5
%-4.2f 左对齐,宽度为4,保留两位小数
不加横线"-"表示右对齐。
示例:
输出一个字符: # printf "%.1s" abc a 保留一个小数点: # printf "%.1f" 1.333 1.3 输出换行: # printf "%.1f\n" 1.333 1.3 格式化输出: # printf "user: %s\tpass: %d\n" abc 123 user: abc pass: 1 左对齐宽度10: # printf "%-10s %-10s %-10s\n" ID Name Number ID Name Number 右对齐宽度10: # printf "%10s %10s %10s\n" ID Name Number ID Name Number 每段对齐: # printf "%10s\n" ID Name Number ID Name Number # printf "%-10s\n" ID Name Number ID Name Number
11.4 cat
功能:连接文件和标准输出打印
常用选项:
-A 查看所有内容
-b 显示非空行行号
-n 显示所有行行号
-T 显示tab,用^I表示
-E 显示以$结尾
示例:
连接两个文件: # cat a b # cat << EOF > 123 > abc > EOF 123 abc 将eof标准输入作为cat标准输出再写到a.txt: # cat > a.txt << eof > 123 > abc > eof
11.5 tac
功能:连接文件和倒序打印文件
常用选项:
示例:
倒序打印每一行:
# tac a.txt
11.6 rev
功能:反向打印文件的每一行
常用选项:
示例:
# echo "123" |rev 321
11.7 wc
功能:统计文件行数、字节、字符数
常用选项:
-c 打印文件字节数
-m 打印文件字符数
-l 打印多少行
示例:
统计文件多少行: # wc -l a.txt
11.8 cp
功能:复制文件或目录
常用选项:
-a 归档
-b 目标文件存在创建备份,备份文件是文件名跟~
-f 强制复制文件或目录
-r 递归复制目录
-p 保留原有文件或目录属性
-i 覆盖文件之前先询问用户
-u 当源文件比目的文件修改时间新时才复制
-v 显示复制信息
示例:
复制目录: # cp -rf test /opt
11.9 mkdir
功能:创建目录
常用选项:
-p 递归创建目录
-v 显示创建过程
示例:
创建多级目录: # mkdir /opt/test/abc 创建多个目录: # mkdir {install,tmp} 创建连续目录: # mkdir {a..c}
11.10 mv
功能:移动文件或重命名
常用选项:
-b 目标文件存在创建备份,备份文件是文件名跟~
-u 当源文件比目的文件修改时间新时才移动
-v 显示移动信息
示例:
移动文件: # mv a.txt /opt 重命名文件: # mv a.txt b.txt
11.11 rename
功能:重命名文件,支持通配符
常用选项:
示例:批量命名文件
将foo1-foo9替换为foo01-foo09: # rename foo foo0 foo? 将以.htm后缀的文件替换为.html: # rename .htm .html *.htm
11.12 dirname
功能:去除路径的最后一个名字
常用选项:
示例:
# dirname /usr/bin/ /usr # dirname dir1/str dir1 dir2 # dirname stdio.h .
11.13 basename
功能:打印路径的最后一个名字
常用选项:
-a 支持多个参数
-s 删除后面的后缀
示例:
# basename /usr/bin/sort sort # basename include/stdio.h .h stdio # basename -s .h include/stdio.h stdio # basename -a any/str1 any/str2 str1 str2
11.14 du
功能:估算文件磁盘空间使用
常用选项:
-b 单位bytes显示
-c 产生一个总大小
-h 易读格式显示(K,M,G)
-k 单位KB显示
-m 单位MB显示
-s 只显示总大小
--max-depth=<目录层数>,超过层数的目录忽略
--exclude=file 排除文件或目录
--time 显示大小和创建时间
示例:
查看目录大小: # du -sh /opt 排除目录某个文件: # du -sh --exclude=test /opt
11.15 cut
功能:选取文件的每一行数据
常用选项:
-b 选中第几个字符、
-c 选中多少个字符
-d 指定分隔符,默认是空格
-f 指定显示选中字段
示例:
打印b字符: # echo "abc" |cut -b "2" b 截取abc字符: # echo "abcdef" |cut -c 1-3 abc 已冒号分隔,显示第二个字段: # echo "a:b:c" |cut -d: -f2 b
11.16 tr
功能:替换或删除字符
格式:Usage:tr [OPTION]... SET1 [SET2]
常用选项:
-c 替换SET1没有SET2的字符
-d 删除SET1中字符
-s 压缩SET1中重复的字符
-t 将SET1用SET2转换,默认
示例:
替换SET1没有SET2的字符: # echo -n "aaabbbccc" | tr -c c 1 111111ccc 去重字符: # echo aaacccddd | tr -s '[a-z]' acd 删除字符: # echo aaabbbccc | tr -d bbb aaaccc 替换字符: # echo aaabbbccc | tr '[a-z]' '[A-Z]' AAABBBCCC 删除换行符: # echo -e "a\nb\nc" | tr -d '\n' abc
11.17 stat
功能:显示文件或文件系统状态
常用选项:
-Z 显示selinux安全上下文
-f 显示文件系统状态
-c 指定格式输出内容
-t 以简洁的形式打印
示例:
显示文件信息: # stat file 只显示文件修改时间: # stat -c %y file
11.18 seq
功能:打印序列化数字
常用选项:
-f 使用printf样式格式
-s 指定分隔符,默认换行符\n
-w 等宽,用0填充
示例:
数字序列: # seq 3 1 2 3 带0的数字序列: # seq -w 03 01 02 03 范围数字序列: # seq 2 5 2 3 4 5 步长序列: # seq 1 2 5 # 2是步长 1 3 5 以冒号分隔序列: # seq -s "+" 5 1+2+3+4+5 等宽并在数字前面加字符串: # seq -f "str%02g" 3 # %g是默认数字位数,02是数字不足2位时用0填充。 str01 str02 str03
11.19 shuf
功能:生成随机序列
常用选项:
-i 输出数字范围
-o 结果写入文件
示例:
输出范围随机数:
# seq 5 |shuf 2 1 5 4 3 # shuf -i 5-10 8 10 7 9 6 5
11.20 sort
功能:排序文本
常用选项:
-f 忽略大小写
-g 一般数字排序
-M 根据月份比较排序,比如JAN、DEC
-h 易读的大小单位排序,比如2K、1G
-n 数字比较排序
-r 倒序排序
-k n,m 根据关键字排序,从第n字段开始,m字段结束
-o 将结果写入文件
-t 指定分隔符
-u 去重重复行
默认是对整列排序。
示例:
随机数字排序: # seq 5 |shuf |sort 随机字母排序: # printf "%c\n" {a..f} |shuf |sort 倒序排序: # seq 5 |shuf |sort -r 分隔后的字段排序: # cat /etc/passwd |sort -t : -k 3 -n 去重重复行: # echo -e "1\n1\n2\n3\n3" |sort -u 大小单位排序: # du -h |sort -k 1 -h -r 分隔后第一个字段的第二个字符排序: # echo -e "fa:1\neb:2\ncc:3" |sort -t : -k 1.2 tab作为分隔符: # sort -t $"\t" file文件内容: zhangsan 6 100 lisi 8 80 wangwu 7 90 zhaoliu 9 70 对file文件的第二列正序排序,再次基础再对第三列倒序排序(多列排序): # sort -k 2,2 -n -k 3,3 -nr file zhaoliu 9 70 lisi 8 80 wangwu 7 90 zhangsan 6 100 对两个文件同时排序: # sort file1 file2
11.21 uniq
功能:去除重复行
常用选项:
-c 打印出现的次数,只能统计相邻的
-d 只打印重复行
-u 只打印不重复行
-D 只打印重复行,并且把所有重复行打印出来
-f n 忽略第n个字段
-i 忽略大小写
-s n 忽略前N个字符
-w 比较不超过前N个字符
示例:
测试文本如下: # cat file abc cde xyz cde xyz abd 去重复行: # sort file |uniq abc abd cde xyz 打印每行重复次数: # sort file |uniq -c 1 abc 1 abd 2 cde 2 xyz 打印不重复行: # sort file |uniq -u abc abd 打印重复行: # sort file |uniq -d cde xyz 打印重复行并统计出现次数: # sort file |uniq -d -c 2 cde 2 xyz 根据前几个字符去重: # sort file |uniq -w 2 abc cde xyz
11.22 tee
功能:从标准输入读取写到标准输出和文件
常用选项:
-a 追加到文件
示例:
打印并追加到文件: # echo 123 |tee -a a.log
11.23 join
功能:连接两个文件
常用选项:
-a <1或2> 除显示原来输出的内容外,还显示指定文件中没有相同的栏位,默认不显示
-i 忽略大小写
-o 按照指定文件栏位显示
-t 使用字符作为输入和输出字段分隔符
-1 连接文件1的指定栏位
-2 连接文件2的指定栏位
示例:
将两个文件相同字段合并一行,其余不输出: # join file1 file2 打印file1第一个列,第file2第二列: # join -o 1.1 2.2 file1 file2 同时打印file1没有的相同字段: # join -a1 file1 file2
11.24 paste
功能:合并文件
常用选项:
-d 指定分隔符,默认是tab键
-s 将文件内容平行,tab键分隔
示例:
两个文件合并,以tab键分隔: # paste a.txt b.txt 两个文件合并,+号分隔: # paste a.txt b.txt -s -d "+" 文件内容平行显示,tab键分隔: # paste -s a.txt
11.25 head
功能:输出文件的前几行
常用选项:
-c 打印前多少K、bytes
-n 打印前多少行
示例:
打印文件前50行: # head -n 50 file
11.26 tail
功能:输出文件的后几行
常用选项:
-c 打印前多少K、bytes
-f 实时读文件,随着文件输出附加输出
-n 输出最后几行
--pid 与-f一起使用,表示pid死掉后结束
-s 与-f一起使用,表示休眠多少秒输出
示例:
打印文件后50行: # tail -n 50 file 实时输出新增行: # tail –f file
11.27 find
功能:搜索文件目录层次结构
格式:find path -optionactions
常用选项:
-name 文件名,支持(‘*’, ‘?’, and ‘[]’)
-type 文件类型,d目录,f常规文件等
-perm 符合权限的文件,比如755
-atime -/+n 在n天以内/过去n天被访问过
-ctime -/+n 在n天以内/过去n天被修改过
-amin -/+n 在n天以内/过去n分钟被访问过
-cmin -/+n 在n天以内/过去n分钟被修改过
-size -/+n 文件大小小于/大于,b、k、M、G
-maxdepth levels 目录层次显示的最大深度
-regex pattern 文件名匹配正则表达式模式
-inum 通过inode编号查找文件
动作:
-detele 删除文件
-exec command {} \; 执行命令,花括号代表当前文件
-ls 列出当前文件,ls -dils格式
-print 完整的文件名并添加一个回车换行符
-print0 打印完整的文件名并不添加一个回车换行符
-printf format 打印格式
示例:
查找文件名: # find / -name "*http*" 查找文件名并且文件类型: # find /tmp -name core -type f -print 查找文件名并且文件类型删除: # find /tmp -depth -name core -type f -delete 查找当前目录常规文件并查看文件类型: # find . -type f -exec file '{}' \; 查找文件权限是664: # find . -perm 664 查找大于1024k的文件: # find . -size -1024k 查找3天内修改的文件: # find /bin -ctime -3 排除多个类型的文件: # find . ! -name "*.sql" ! -name "*.txt" 或条件查找多个类型的文件: # find . -name '*.sh' -o -name '*.bak' # find . -regex ".*\.sh|.*\.bak" # find . -regex ".*\.\(sh\|bak\)" 并且条件查找文件: # find . -name "*.sql" -a -size +1024k 只显示第一级目录: # find /etc -type d -maxdepth 1 通过inode编号删除文件: # rm `find . -inum 671915` # find . -inum 8651577 -exec rm -i {} \;
11.28 xargs
功能:从标准输入执行命令
常用选项:
-a file 从指定文件读取数据作为标准输入
-0 处理包含空格的文件名,print0
-d delimiter 分隔符,默认是空格分隔显示
-i 标准输入的结果以{}代替
-I 标准输入的结果以指定的名字代替
-t 显示执行命令
-p 交互式提示是否执行命令
-n 最大命令行参数
--show-limits 查看系统命令行长度限制
示例:
删除/tmp下名字是core的文件: # find /tmp -name core -type f -print | xargs /bin/rm -f # find /tmp -name core -type f -print0 | xargs -0 /bin/rm -f 列转行(去除换行符 ): # cut -d: -f1 < /etc/passwd | sort | xargs echo 行转列: # echo "1 2 3 4 5" |xargs -n1 最长两列显示: # echo "1 2 3 4 5" |xargs -n2 创建未来十天时间: # seq 1 10 |xargs -i date -d "{} days " +%Y-%m-%d 复制多个目录: # echo dir1 dir2 |xargs -n1 cp a.txt 清空所有日志: # find ./ -name "*.log" |xargs -i tee {} # echo ""> {} 这样不行,>把命令中断了 rm在删除大量的文件时,会提示参数过长,那么可以使用xargs删除: # ls |xargs rm –rf 或分配删除 rm [a-n]* -rf # getconf ARG_MAX 获取系统最大参数限制
11.29 nl
功能:打印文件行号
常用选项:
-b 指定行号显示方式,a表示所有行都打印行号,b表示空行不显示行号,默认是a
-n 行号显示方法,ln左对齐,rn右对齐,rz右边显示,左边空白用0填充。
-w 行号栏位在左边占用的宽度
示例:
打印行号,空行不显示: # nl a.txt 左对齐打印行号: # nl -n ln a.txt 行号右移动五个空格: # nl -w 5 a.txt
11.30 date
功能:打印或设置系统日期和时间
常用选项:
-d string 显示时间所描述的字符串
-f datefile 读取文件的每一行
-I 输出ISO 8601格式的日期和时间
-r 显示文件的最后修改时间
-R 输出RFC 2822格式的日期和时间
-s string 设置时间所描述的字符串
-u 打印或设置UTC时间
控制输出格式:
%n : 下一行
%t : 跳格
%H : 小时(00..23)
%I : 小时(01..12)
%k : 小时(0..23)
%l : 小时(1..12)
%M : 分钟(00..59)
%p : 显示本地 AM 或 PM
%r : 直接显示时间 (12 小时制,格式为 hh:mm:ss [AP]M)
%s : 从 1970 年 1 月 1 日 00:00:00 UTC 到目前为止的秒数
%S : 秒(00..61)
%T : 直接显示时间 (24 小时制)
%X : 相当于 %H:%M:%S
%Z : 显示时区 %a : 星期几 (Sun..Sat)
%A : 星期几 (Sunday..Saturday)
%b : 月份 (Jan..Dec)
%B : 月份 (January..December)
%c : 直接显示日期与时间
%d : 日 (01..31)
%D : 直接显示日期 (mm/dd/yy)
%h : 同 %b
%j : 一年中的第几天 (001..366)
%m : 月份 (01..12)
%U : 一年中的第几周 (00..53) (以Sunday为一周的第一天的情形)
%w : 一周中的第几天 (0..6)
%W : 一年中的第几周 (00..53) (以Monday为一周的第一天的情形)
%x : 直接显示日期 (mm/dd/yy)
%y : 年份的最后两位数字 (00.99)
%Y : 完整年份 (0000..9999)
示例:
设置系统日期和时间: # date -s "2016-12-15 00:00:00" 查看当前系统时间戳: # date +%s 查看当前系统时间: # date +'%F %T' 把日期和时间转换成时间戳: # date -d "2016-12-15 18:00:00" +%s 把时间戳转成时间: # date -d '@1481842800' '+%F %T' 时间加减: 显示前一分钟:date -d '-1 minute' +'%F %T' 显示上一周:date -d '-1 week' +'%F %T' 显示前一天日期:date +%F -d '+1 day' 显示后一天日期:date +%F -d '-1 day' 显示上一个月日期:date +%F -d '+1 month' 显示下一个月日期:date +%F -d '-1 month' 显示上一年日期:date +%F -d '+1 year' 显示下一年日期:date +%F -d '-1 year' 或 显示前一天日期:date -d yesterday +%F 显示后一天日期:date -d tomorrow +%F 天为单位,显示前一天现在时间:date -d '1 day ago' +'%F %T' 秒为单位,显示一小时前现在时间:date -d '3600 second ago' +'%F %T' 时间比较: NOW_DATE=$(date +'%F %T') AGO_DATE=$(date -d "2016-12-15 18:00:00" +%s) [ $NOW_DATE -gt $AGO_DATE ] && echo yes || echo no