本章节学习一些在编写Shell时的常用命令或工具及使用技巧。有人说Shell脚本是命令堆积的一个文件,按顺序去执行。还有人说想学好Shell脚本,要把Linux上各种常见的命令或工具掌握了,这些说法都没错。由于Shell语言本身在语法结构上比较简单,是面向过程编程,想实现复杂的功能有点强人所难!而且Shell本身又工作在Linux内核之上,在用户态调用Linux命令会很方面,所以大多数情况下我们都是依靠这些命令来完成脚本中的某些功能,比如文本处理、获取系统状态等等,然后通过Shell语法结构组织代码逻辑。不管是学Linux系统好还是写Shell脚本也好,有些命令都是必须要会的,以下是根据个人经验总结的一些常用的命令。

怎么更好的学习命令呢?

当然查看官方帮助文档了,可以通过man cmd、cmd --help、help cmd、infocmd等方式查看命令的使用。

本章内容如下:

第十一章  Shell常用命令与工具(一)_Linux

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}

博客地址:http://lizhenliang.blog.51cto.com

QQ群:323779636(Shell/Python运维开发群)

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

博客地址:http://lizhenliang.blog.51cto.com

QQ群:323779636(Shell/Python运维开发群)

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|t>       指定行号显示方式,a表示所有行都打印行号,b表示空行不显示行号,默认是a

-n <ln|rn|rz>  行号显示方法,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