1. 文件查找命令
1.1 find命令
语法格式:find 搜索路径 [选项] 搜索内容
| 选项 | 解析 | 
| -name | 按照文件名搜索 | 
| -iname | 按照文件名搜索,不区分文件名大小 | 
| -inum | 按照 inode 号搜索 | 
| -type | 根据文件类型(f:文件,d:目录,c:字符设备文件,b:块设备文件,l:链接文件,p:管道文件)搜索 | 
| -size | 根据文件大小(单位:ckMGTP)搜索, -小于,+大于,例如查找/etc目录下大于1M的文件:find /etc -size +1M | 
| -mtime | 根据修改时间(单位:smhdw)搜索 | 
| -ctime | 根据创建时间(单位:smhdw)搜索 | 
| -atime | 根据被访问时的时间间隔(单位:smhdw)搜索 | 
| -mmin | n分钟以(-n:内,+n:外)内修改的文件 | 
| -mindepth | 从n级子目录开始搜索,最多搜索到n-1级子目录 | 
| -depth | 检索深度为 n 的文件,即位于指定目录以下 n 层的文件 | 
| -empty | 检索空文件或空目录 | 
| -perm | 根据文件权限搜索 | 
| -ls | 打印搜索到的文件的详细信息 | 
| -delete | 删除检索到的文件 | 
| -exec | 对搜索的文件常用操作("-exec"和"-ok"相似,对文件执行特定的操作,"-ok"得到确认命令后,才会执行;-print打印输出) | 
1.2 locate命令
- locate命令,不同于find命令是在整块磁盘中搜索,locate命令是在数据库文件中查找- 
- find是默认全局匹配,locate则是默认部分匹配
- 文件更新后,用updatedb命令把文件更新到数据库(默认是第二天系统才会自动更新到数据库),否则locate查找不到
 
1.3 whereis命令
- whereis命令,只能用于程序名的搜索- 
- 命令参数:二进制文件(参数-b)、man说明文件(参数-m)和源代码文件(参数-s)。如果省略参数,则返回所有信息。
 
1.4 which命令
- which命令,仅查找二进制程序文件
2. Linux文本处理三剑客
文本处理三剑客工具grep,sed和awk都是基于行处理的,它们会一行行读入数据,处理完一行之后再处理下一行。
2.1 文件处理三剑客之grep
grep命令,用于查找文件里符合条件的字符串。
- 语法格式:
- 语法1:grep [option] [ pattern] [file1, file2..]
- 语法2:command | grep [option] [pattern]
 
| 选项(option) | 解析 | 
| -v | 不显示匹配行信息 | 
| -i | 搜索时忽略大小写 | 
| -n | 显示行号 | 
| -r | 递归搜索 | 
| -E | 支持扩展正则表达式 | 
| -F | 不按正则表达式匹配,按照字符串字面意思匹配 | 
| -c | 只显示匹配行总数 | 
| -w | 匹配整词 | 
| -x | 匹配整行 | 
| -l | 只显示文件名,不显示内容 | 
| -s | 不显示错误信息 | 
- grep和- egrep- 
- grep默认不支持扩展正则表达式,只支持基础正则表达式
- 使用grep-E可以支持扩展正则表达式使用
- egrep可以支持扩展正则表达式,与- grep-E等价
 
2.2 文件处理三剑客之sed
sed(Stream Editor),流编辑器。对标准输出或文件逐行进行处理
- 语法格式:
- 语法1:stdout |sed [option] "pattern command"
- 语法2:sed [option] "pattern command" file
 
2.2.1 sed选项
| 选项(option) | 解析 | 
| -n | 只打印模式匹配行 | 
| -e | 直接在命令行进行sed编辑,默认选项 | 
| -f | 编辑动作保存在文件中,指定文件执行 | 
| -r | 支持扩展正则表达式 | 
| -i | 直接修改文件内容 | 
2.2.2 sed匹配模式
| 匹配模式(pattern) | 解析 | 
| 10command | 匹配到第10行 | 
| 10,20command | 匹配从第10行开始,到第20行结束10, | 
| 10,+5command | 匹配从第10行开始,到第16行结束 | 
| /pattern1/command | 匹配到pattern1的行 | 
| /pattern1/,/pattern2/command | 匹配到pattern1的行开始,到匹配到patern2的行结束 | 
| 10,/pattern1/command | 匹配从第10行开始,到匹配到pettern1的行结束 | 
| /pattern1/,10command | 匹配到pattern1的行开始,到第10行匹配结束 | 
# 打印test.txt文件的第17行
sed -n "17p" test.txt
# 打印文件的10到20行
sed -n "10,20p" test.txt
# 打印test.txt文件中从第10行开始,往后面加5行
sed -n "10,+5p" test.txt
# 打印test.txt文件中以root开头的行
sed -n "/^root/p" test.txt
# 打印test.txt文件中第一个匹配到以ftp开头的行,到mail开头的行结束
sed -n "/^ftp/,/^mail/p" test.txt
# 打印test.txt文件中从第4行开始匹配,直到以hdfs开头的行结束
sed -n "4,/^hdfs/p" test.txt
# 打印test.txt文件中匹配root的行,直到第10行结束
sed -n "/root/,10p"test.txt
2.2.3 sed中的编辑命令
| 编辑命令 | 类别 | 含义 | 
| p | 查询 | 打印 | 
| = | 查询 | 只显示行号 | 
| a | 增加 | 行后追加 | 
| i | 增加 | 行前追加 | 
| r | 增加 | 外部文件读入,行后追加 | 
| w | 增加 | 匹配行写入外部文件 | 
| d | 删除 | 删除 | 
| s/old/new | 修改 | 将行内第一个old替换为new | 
| s/old/new/g | 修改 | 将行内全部的old替换为new | 
| s/old/new/2g | 修改 | 将行内从第2个old开始到剩下所有的old替换为new | 
| s/old/new/ig | 修改 | 将行内全部的old替换为new,忽略大小写 | 
反向引用
[cmuser@localhost test]$ cat abc.txt
First Line
Second haha
[cmuser@localhost test]$ sed -i 's/Sec..d/&s/g' abc.txt
[cmuser@localhost test]$ cat abc.txt
First Line
Seconds haha
[cmuser@localhost test]$ sed -i 's/\(Sec..ds\)/\10/g' abc.txt
[cmuser@localhost test]$ cat abc.txt
First Line
Seconds0 haha
[cmuser@localhost test]$ sed -i 's/\(Sec\)...../\1FFFFFFFFFF/g' abc.txt
[cmuser@localhost test]$ cat abc.txt
First Line
SecFFFFFFFFFF haha
- 
&和\1引用模式匹配到的整个串
 
- 两者区别在于只能表示匹配到的完整字符串,只能引用整个字符串;而\1可以使用()匹配到的字符
 
- 
sed中引用变量时注意事项: 
- 匹配模式中存在变量,则建议使用双引号
- sed中需要引入自定义变量时,如果外面使用单引号,则自定义变量也必须使用单引号
 
[cmuser@localhost test]$ old_str=First
[cmuser@localhost test]$ new_str=One
[cmuser@localhost test]$ sed -i "s/$old_str"/"$new_str/g" abc.txt
[cmuser@localhost test]$ cat abc.txt
One Line
SecFFFFFFFFFF haha
2.2.4 sed实例
- sed查找文件内容(处理一个MySQL配置文件my.cnf的文本,示例如下;编写脚本实现以下功能:输出文件有几个段,并且针对每个段可以统计配置参数总个数)
[jenkins@caimeidev1 test]$ vim test1.sh
#!/bin/bash
FILE_NAME=/etc/my.cnf
function get_all_segments {
    echo "`sed -n '/\[.*\]/p' $FILE_NAME |sed -e 's/\[//g' -e 's/\]//g'`"
}
function count_items_in_segment {
    echo "`sed -n '/\['$1'\]/,/\[.*\]/p' $FILE_NAME  | grep -v ^# |grep -v ^$ |grep -v "\[.*\]" |wc -l `"
}
num=0
for seg in `get_all_segments`
do
    num=`expr $num + 1`
    items_count=`count_items_in_segment $seg`
    echo "$num:$seg  $items_count"
done
输出结果:
[jenkins@caimeidev1 test]$ ./test1.sh
1:mysqld  9
2:mysqld_safe  2
3:mysql  1
4:client  1
- sed删除和修改文件内容
# 删除文件中的所有注释行和空行
sed -i '/[:blank:]*#/d;/^$/d' nginx.conf
# 在配置文件中所有不以#开头的行前面添加*符号,注意:以#开头的行不添加
sed -i 's/^[^#]/\*&/g' nginx.conf
# 修改/etc/passwd中第1行中第1个root为ROOT	
sed -i '1s/root/ROOT/' passwd
# 修改/etc/passwd中第5行到第10行中所有的/sbin/nologin为/bin/bash
sed -i '5,10s/\/sbin\/nologin/\/bin\/bash/g' passwd
# 修改/etc/passwd中匹配到/sbin/nologin的行,将匹配到行中的login改为大写的LOGIN
sed -i '/\/sbin\/nologin/s/login/LOGIN/g' passwd
# 修改/etc/passwd中从匹配到以root开头的行,到匹配到行中包含mail的所有行。修改内为将这些所有匹配到的行中的bin改为HADOOP
sed -i '/^root/,/mail/s/bin/HADOOP/g' passwd
# 修改/etc/passwd中从匹配到以root开头的行,到第15行中的所有行,修改内容为将这些行中的nologin修改为SPARK
sed -i '/^root/,15s/nologin/SPARK/g' passwd
# 修改/etc/passwd中从第15行开始,到匹配到以yarn开头的所有行,修改内容为将这些行中的bin换位BIN
sed -i '15,/^yarn/s/bin/BIN/g' passwd 
- sed追加文件内容(a:在匹配行后面追加,i:在匹配行前面追加,r:将文件内容追加到匹配行后面,w:将匹配行写入指定文件)
# a:在匹配行后面追加
# (1)、passwd文件第10行后面追加"Add Line Behind"		
sed -i '10a Add Line Begind' passwd
# (2)、passwd文件第10行到第20行,每一行后面都追加"Test Line Behind"
sed -i '10,20a Test Line Behind' passwd
# (3)、passwd文件匹配到/bin/bash的行后面追加"Insert Line For /bin/bash Behind"
sed -i '/\/bin\/bash/a Insert Line For /bin/bash Behind' passwd
# i:在匹配行前面追加
# (1)、passwd文件匹配到以yarn开头的行,在匹配行前面追加"Add Line Before"
sed -i '/^yarn/i Add Line Before' passwd
# (2)、passwd文件每一行前面都追加"Insert Line Before Every Line"
sed -i 'i Insert Line Before Every Line' passwd
# r:将文件内容追加到匹配行后面
# (1)、将/etc/fstab文件的内容追加到passwd文件的第20行后面
sed -i '20r /etc/fstab' passwd
# (2)、将/etc/inittab文件内容追加到passwd文件匹配/bin/bash行的后面
sed -i '/\/bin\/bash/r /etc/inittab' passwd
# (3)、将/etc/vconsole.conf文件内容追加到passwd文件中特定行后面,匹配以ftp开头的行,到第18行的所有行
sed -i '//,18r /etc/vconsole.conf' passwd
# w:将匹配行写入指定文件	
# (1)、将passwd文件匹配到/bin/bash的行追加到/tmp/sed.txt文件中
sed -i '/\/bin\/bash/w /tmp/sed.txt' passwd
# (2)、将passwd文件从第10行开始,到匹配到hdfs开头的所有行内容追加到/tmp/sed-1.txt
sed -i '10,/^hdfs/w /tmp/sed-1.txt' passwd
2.3 文件处理三剑客之awk
awk是一个文本处理工具,通常用于处理数据并生成结果报告
awk 'BEGIN{} pattern{commands}END{}' file_name
standard output | awk 'BEGIN{}pattern{commands}END{}'
| 语法格式 | 解析 | 
| BEGIN{} | 正式处理数据之前执行 | 
| pattern | 匹配模式 | 
| {commands} | 处理命令,可能多行 | 
| END{} | 处理完所有匹配数据后执行 | 
2.3.1 awk内置变量
| 内置变量 | 解析 | 
| $0 | 打印行所有信息 | 
| $1~$n | 打印行的第1到n个字段的信息 | 
| NF | Number Field 处理行的字段个数 | 
| NR | Number Row 处理行的行号,从1开始计数 | 
| FNR | File Number Row 多文件处理时,每个文件单独记录行号,都是从0康凯斯 | 
| FS | Field Separator 字段分割符,不指定时默认以空格或tab键分割 | 
| RS | Row Separator 行分隔符,不指定时以回车分割\n | 
| OFS | Output Filed Separator 输出字段分隔符。 | 
| ORS | Output Row Separator 输出行分隔符 | 
| FILENAME | 处理文件的文件名 | 
| ARGC | 命令行参数个数 | 
| ARGV | 命令行参数数组 | 
[cmuser@localhost test]$ awk '{print $0}' abc.txt
One Line
SecFFFFFFFFFF haha
[cmuser@localhost test]$ awk '{print $1}' abc.txt
One
SecFFFFFFFFFF
[cmuser@localhost test]$ awk '{print NR}' abc.txt
1
2
2.3.2 awk格式化输出之printf
| 格式符 | 解析 | 
| %s | 打印字符串 | 
| %d | 打印10进制数 | 
| %f | 打印浮点数 | 
| %x | 打印16进制数 | 
| %o | 打印8进制数 | 
| %e | 打印数字的科学计数法格式 | 
| %c | 打印单个字符的ASCII码 | 
| 修饰符 | 解析 | 
| - | 左对齐 | 
| + | 右对齐 | 
| # | 显示8进制在前面加o,显示16进制在前面加0x | 
# 1、以字符串格式打印/etc/passwd中的第7个字段,以":"作为分隔符
awk 'BEGIN{FS=":"} {printf "%s\n",$7}' /etc/passwd
# 2、以10进制格式打印/etc/passwd中的第3个字段,以":"作为分隔符
awk 'BEGIN{FS=":"} {printf "%d\n",$3}' /etc/passwd
# 3、以浮点数格式打印/etc/passwd中的第3个字段,以":"作为分隔符
awk 'BEGIN{FS=":"} {printf "%0.3f\n",$3}' /etc/passwd
# 4、以16进制数格式打印/etc/passwd中的第3个字段,以":"作为分隔符
awk 'BEGIN{FS=":"} {printf "%#x\n",$3}' /etc/passwd
# 5、以8进制数格式打印/etc/passwd中的第3个字段,以":"作为分隔符
awk 'BEGIN{FS=":"} {printf "%#o\n",$3}' /etc/passwd
# 6、以科学计数法格式打印/etc/passwd中的第3个字段,以":"作为分隔符
awk 'BEGIN{FS=":"} {printf "%e\n",$3}' /etc/passwd
2.3.3 awk模式匹配的两种用法
- awk模式匹配:- 
- RegExp:按正则表达式匹配
- 关系运算匹配:按关系运算匹配
 
- RegExp(正则表达式匹配)
# 匹配/etc/passwd文件行中含有root字符串的所有行
awk 'BEGIN{FS=":"}/root/{print $0}' /etc/passwd
# 匹配/etc/passwd文件行中以yarn开头的所有行
awk 'BEGIN{FS=":"}/^yarn/{print $0}' /etc/passwd
- 运算符匹配(<:小于,>:大于,<=:小于等于,>=:大于等于,==:等于,!=:不等于,~:匹配正则表达式,!~:不匹配正则表达式)
# 以:为分隔符,匹配/etc/passwd文件中第3个字段小于50的所有行信息
awk 'BEGIN{FS=":"}$3<50{print $0}' /etc/passwd
# 以:为分隔符,匹配/etc/passwd文件中第3个字段大于50的所有行信息
awk 'BEGIN{FS=":"}$3>50{print $0}' /etc/passwd
# 以:为分隔符,匹配/etc/passwd文件中第7个字段为/bin/bash的所有行信息
awk 'BEGIN{FS=":"}$7=="/bin/bash"{print $0}' /etc/passwd
# 以:为分隔符,匹配/etc/passwd文件中第7个字段不为/bin/bash的所有行信息
awk 'BEGIN{FS=":"}$7!="/bin/bash"{print $0}' /etc/passwd
# 以:为分隔符,匹配/etc/passwd中第3个字段包含3个以上数字的所有行信息
awk 'BEGIN{FS=":"}$3~/[0-9]{3,}/{print $0}' /etc/passwd
- 布尔运算符匹配(||:或,&&:与,!:非)
# 以:为分隔符,匹配/etc/passwd文件中包含hdfs或yarn的所有行信息
awk 'BEGIN{FS=":"}$1=="hdfs" || $1=="yarn" {print $0}' /etc/passwd
# 以:为分隔符,匹配/etc/passwd文件中第3个字段小于50并且第4个字段大于50的所有行信息
awk 'BEGIN{FS=":"}$3<50 && $4>50 {print $0}' /etc/passwd
2.3.4 awk表达式用法
| 运算符 | 解析 | 
| + | 加 | 
| / | 除 | 
| % | 模 | 
| ^或** | 乘方 | 
| ++x | 在返回x变量之前,×变量加1 | 
| X++ | 在返回x变量之后,×变量加1 | 
# 使用awk计算/etc/services中的空白行数量
awk '/^$/{sum++}END{print sum}' /etc/services
2.3.5 awk动作中的条件及循环语句
# 以:为分隔符,只打印/etc/passwd中第3个字段的数值在50-100范围内的行信息
awk 'BEGIN{FS=":"}{
    if($3<50){ 
        printf "%-20s%-20s%-5d\n","小于50的UID",$1,$3
    } else if($3>100) {
        printf "%-20s%-20s%-5d\n","大 于100的UID",$1,$3
    } else{
        printf "%-20s%-20s%-5d\n","大于50 小于100的UID",$1,$3
    }
}' /etc/passwd
2.3.6 awk中的字符串函数
| 函数名 | 解析 | 
| length(str) | 计算长度 | 
| index(str1,str2) | 返回在str1中查询到的str2的位置 | 
| tolower(str) | 小写转换 | 
| toupper(str) | 大写转换 | 
| split(str,arr,fs) | 分隔字符串,并保存到数组中 | 
| match(str,RE) | 返回正则表达式匹配到的子串的位置 | 
| substr(str,m,n) | 截取子串,从m个字符开始,截取n位。n若不指定,则默认截取到字符串尾 | 
| sub(RE,RepStr,str) | 替换查找到的第一个子串 | 
| gsub(RE,RepStr,str) | 替换查找到的所有子串 | 
# 搜索字符串"I have a dream"中出现"ea"子串的位置
awk 'BEGIN{str="I hava a dream";location=index(str,"ea");print location}
awk 'BEGIN{str="I hava a dream";location=match(str,"ea");print location}'
# 将字符串"Hadoop is a bigdata Framawork"全部转换为小写
awk 'BEGIN{str="Hadoop is a bigdata Framework";print tolower(str)}'
# 将字符串"Hadoop is a bigdata Framawork"全部转换为大写
awk 'BEGIN{str="Hadoop is a bigdata Framework";print toupper(str)}'
# 将字符串"Hadoop Kafka Spark Storm HDFS YARN Zookeeper",按照空格为分隔符,分隔每部分保存到数组array中
awk 'BEGIN{str="Hadoop Kafka Spark Storm HDFS YARN Zookeeper";split(str,arr," ");for(a in arr) print arr[a]}'
# 搜索字符串"Tranction 2345 Start:Select * from master"第一个数字出现的位置
awk 'BEGIN{str="Tranction 2345 Start:Select * from master";location=match(str,/[0-9]/);print location}'
# 截取字符串"transaction start"的子串,截取条件从第4个字符开始,截取5位
awk 'BEGIN{str="transaction start";print substr(str,4,5)}'
# 替换字符串"Tranction 243 Start,Event ID:9002"中第一个匹配到的数字串为$符号
awk 'BEGIN{str="Tranction 243 Start,Event ID:9002";count=sub(/[0-9]+/,"$",str);print count,str}'
awk 'BEGIN{str="Tranction 243 Start,Event ID:9002";count=gsub(/[0-9]+/,"$",str);print count,str}'
2.3.7 awk的常用选项
| 选项 | 解析 | 
| -v | 参数传递 | 
| -f | 指定脚本文件 | 
| -F | 指定分隔符 | 
| -V | 查看awk的版本号 | 
2.3.8 awk中数组的用法
在awk中,使用数组时,不仅可以使用1.2…n作为数组下标,也可以使用字符串作为数组下标。
# 打印元素:
echo ${array[2]}
# 打印元素个数:
echo ${#array[@]}
# 打印元素长度:
echo ${#array[3]}
# 给元素赋值:
array[3]="Li"
# 删除元素:
unset array[2];unset array
# 分片访问:
echo ${array[@]:1:3}
# 元素内容替换:
${array[@]/e/E}只替换第一个e;
$tarray[@]//e/E}替换所有的e
# 数组的遍历:
for a in array 
do
	echo $a 
done 
# 使用字符串作为数组下标
array["var1"]="Jin"
array["var2"]="Hao"
array["var3"]="Fang"
for(a in array)
	print array[a]
# 统计主机上所有的TCP连接状态数,按照每个TCP状态分类
netstat -an | grep tcp | awk '{array[$6]++} END{for(a in array) print a,array[a]}'
END .