【2024版】最新shell安装使用教程(非常详细)零基础入门到精通,收藏这一篇就够了

299 篇文章 23 订阅
262 篇文章 10 订阅

awk

awk功能

  
NR代表行数,$n取某一列,$NF最后一列  
  
NR==20,NR==30 从20行到30行  
  
FS竖着切,列的分隔符  
  
RS横着切,行的分隔符  

语法

  
awk \[–F\] \[“\[分隔符\]”\] \[’{print$1,$NF}’\] \[目标文件\]  
  
awk 'BEGIN{FS="\[列分隔符\]+";RS="\[行分隔符\]+";print "-GEGIN-"} NR==n{动作} END{print "-END-"}' xxx.txt  

内置变量

  
$n 当前记录的第n个字段,字段间由 FS分隔。  
  
$0 完整的输入记录。  
  
ARGC 命 令行参数的数目。  
  
ARGIND 命令行中当前文件的位置(从0开始算)。  
  
ARGV 包 含命令行参数的数组。  
  
CONVFMT 数字转换格式(默认值为%.6g)  
  
ENVIRON 环 境变量关联数组。  
  
ERRNO 最后一个系统错误的描述。  
  
FIELDWIDTHS 字 段宽度列表(用空格键分隔)。  
  
FILENAME 当前文件名。  
  
FNR 同 NR,但相对于当前文件。  
  
FS 字段分隔符(默认是任何空格)。  
  
IGNORECASE 如 果为真,则进行忽略大小写的匹配。  
  
NF 当前记录中的字段数。  
  
NR 当 前记录数。  
  
OFMT 数字的输出格式(默认值是%.6g)。  
  
OFS 输 出字段分隔符(默认值是一个空格)。  
  
ORS 输出记录分隔符(默认值是一个换行符)。  
  
RLENGTH 由 match函数所匹配的字符串的长度。  
  
RS 记录分隔符(默认是一个换行符)。  
  
RSTART 由 match函数所匹配的字符串的第一个位置。  
  
SUBSEP 数组下标分隔符(默认值是034)。  

运算符

  
\= += -= \*= /= %= ^= \*\*= 赋值  
  
?: C条件表达式  
  
|| 逻 辑或  
  
&& 逻辑与  
  
~ ~! 匹 配正则表达式和不匹配正则表达式  
  
< <= > >= != == 关 系运算符  
  
空格 连接  
  
\+ - 加,减  
  
\* / & 乘,除与求余  
  
\+ - ! 一元加,减和逻辑非  
  
^ \*\*\* 求幂  
  
++ -- 增加或减少,作为前缀或后缀  
  
$ 字 段引用  
  
in 数组成员  

字符串函数

  
sub 匹配记录中最大、最靠左边的子字符串的正则表达式,并用替换字符串替换这些字符串。如果没有指定目标字符串就默认使用整个记录。替换只发生在第一次匹配的 时候  
gsub 整个文档中进行匹配  
index 返回子字符串第一次被匹配的位置,偏移量从位置1开始  
substr 返回从位置1开始的子字符串,如果指定长度超过实际长度,就返回整个字符串  
split 可按给定的分隔符把字符串分割为一个数组。如果分隔符没提供,则按当前FS值进行分割  
length 返回记录的字符数  
match 返回在字符串中正则表达式位置的索引,如果找不到指定的正则表达式则返回0。match函数会设置内建变量RSTART为字符串中子字符串的开始位 置,RLENGTH为到子字符串末尾的字符个数。substr可利于这些变量来截取字符串  
toupper和tolower 可用于字符串大小间的转换,该功能只在gawk中有效  

  
atan2(x,y) y,x 范围内的余切  
  
cos(x) 余弦函数  
  
exp(x) 求 幂  
int(x) 取整  
log(x) 自然对 数  
rand() 随机数  
sin(x) 正弦  
sqrt(x) 平 方根  
srand(x) x是rand()函数的种子  
int(x) 取 整,过程没有舍入  
rand() 产生一个大于等于0而小于1的随机数  

例子

1、只查看 ett.txt 文件(共 100 行)内第 20 到第 30 行的内容
  
awk ‘NR&gt;19&amp;&amp;NR&lt;31’ ett.txt  
  
awk ‘{ if (NR&gt;19&amp;&amp;NR&lt;31) print $0}’ ett.txt
给文件内容加行号
  
awk ‘{print NR,$0}’ /etc/inittab
输出第24行并且加行号
  
awk ‘NR==24 {print NR,$0}’ /etc/inittab4
标准写法
  
awk -F '\[ :\]+' 'NR==2{print $(NF-1)}' /etc/passwd  
  
相当于   
  
awk 'BEGIN{FS=&quot;\[ :\]+&quot;}NR==2{print $(NF-1)}' /etc/passwd  
  
awk 'BEGIN{RS=&quot;/&quot;} {print $0}' /etc/passwd  

以一个或多个/为行的分割符,打印第二行的第二列,列的分隔符为默认的空格,并打印行号
  
awk 'BEGIN{RS=&quot;\[/\]+&quot;} NR==2{print NR,$2}' test  

正则:

以:为分隔符,打印第5列以s开头的一整行awk -F “:” ‘$5~/^s/{print $0}’ /etc/passwd
以/为分隔符,匹配倒数第二行的s或者没有s后面是bin的整行
  
awk -F &quot;/&quot; '$(NF-1)~/(s|)bin/' /etc/passwd  

匹配第一列以ssh或者ftp或mysql开头或者结尾的行
  
awk '$1~/^(ssh|ftp|mysql)$/{print $1,$2}' /etc/services  

输出结果6 0 1 2
  
echo &quot;6@@@@@@@@@@@@@@@0=============1##############2&quot; |awk -F '\[@=#\]+' '{print $1,$2,$3,$4}'  

awk统计百分比的问题

日志样子举例如下:

http://youku.com 200 http://youku.com 302 http://youku.com 403 http://youku.com 502 http://baidu.com 302 http://baidu.com 404

现想使用awk命令按域名统计 返回码大于等于400的百分比,假如优酷总共有4行,大于等于400的返回码有两行,那占比就为50%

  
awk '{  
  
count\[$1\]++;  
  
if($2&gt;400)above400\[$1\]++  
  
}  
  
END{  
  
for(i in count){  
  
print i, count\[i\], above400\[i\]/count\[i\]}  
  
}' &lt; xxx.txt  

比较

if 中 [ -a --> -z ]
  
\[ -a FILE \]  如果 FILE 存在则为真。    
\[ -b FILE \]  如果 FILE 存在且是一个块特殊文件则为真。    
\[ -c FILE \]  如果 FILE 存在且是一个字特殊文件则为真。    
\[ -d FILE \]  如果 FILE 存在且是一个目录则为真。    
\[ -e FILE \]  如果 FILE 存在则为真。    
\[ -f FILE \]  如果 FILE 存在且是一个普通文件则为真。    
\[ -g FILE \] 如果 FILE 存在且已经设置了SGID则为真。
 \[ -h FILE \]  如果 FILE 存在且是一个符号连接则为真。    
\[ -k FILE \]  如果 FILE 存在且已经设置了粘制位则为真。    
\[ -p FILE \]  如果 FILE 存在且是一个名字管道(F如果O)则为真。    
\[ -r FILE \]  如果 FILE 存在且是可读的则为真。    
\[ -s FILE \]  如果 FILE 存在且大小不为0则为真。    
\[ -t FD \]  如果文件描述符 FD 打开且指向一个终端则为真。    
\[ -u FILE \]  如果 FILE 存在且设置了SUID (set user ID)则为真。    
\[ -w FILE \]  如果 FILE 如果 FILE 存在且是可写的则为真。    
\[ -x FILE \]  如果 FILE 存在且是可执行的则为真。    
\[ -O FILE \]  如果 FILE 存在且属有效用户ID则为真。    
\[ -G FILE \]  如果 FILE 存在且属有效用户组则为真。    
\[ -L FILE \]  如果 FILE 存在且是一个符号连接则为真。    
\[ -N FILE \]  如果 FILE 存在 and has been mod如果ied since it was last read则为真。    
\[ -S FILE \]  如果 FILE 存在且是一个套接字则为真。    
\[ FILE1 -nt FILE2 \]  如果 FILE1 has been changed more recently than FILE2, or 如果 FILE1 exists and FILE2 does not则为真。    
\[ FILE1 -ot FILE2 \]  如果 FILE1 比 FILE2 要老, 或者 FILE2 存在且 FILE1 不存在则为真。    
\[ FILE1 -ef FILE2 \]  如果 FILE1 和 FILE2 指向相同的设备和节点号则为真。    
\[ -o OPTIONNAME \]  如果 shell选项 “OPTIONNAME” 开启则为真。    
\[ -z STRING \]  “STRING” 的长度为零则为真。    
\[ -n STRING \] or \[ STRING \]  “STRING” 的长度为非零 non-zero则为真。    
\[ STRING1 == STRING2 \]  如果2个字符串相同。 “=” may be used instead of “==” for strict POSIX compliance则为真。    
\[ STRING1 != STRING2 \]  如果字符串不相等则为真。   
\[ STRING1 < STRING2 \]  如果 “STRING1” sorts before “STRING2” lexicographically in the current locale则为真。    
\[ STRING1 > STRING2 \]  如果 “STRING1” sorts after “STRING2” lexicographically in the current locale则为真。    
\[ ARG1 OP ARG2 \] “OP” is one of -eq, -ne, -lt, -le, -gt or -ge. These arithmetic binary operators return true if “ARG1” is equal to, not equal to, less than, less than or equal to, greater than, or greater than or equal to “ARG2”, respectively. “ARG1” and “ARG2” are integers.
字符串判断
  
str1 = str2      当两个串有相同内容、长度时为真   
str1 != str2      当串str1和str2不等时为真   
\-n str1        当串的长度大于0时为真(串非空)   
\-z str1        当串的长度为0时为真(空串)   
str1           当串str1为非空时为真  

数字的判断
int1 -eq int2    两数相等为真   
int1 -ne int2    两数不等为真   
int1 -gt int2    int1大于int2为真   
int1 -ge int2    int1大于等于int2为真   
int1 -lt int2    int1小于int2为真   
int1 -le int2    int1小于等于int2为真  

文件的判断
  
\-r file     用户可读为真   
\-w file     用户可写为真   
\-x file     用户可执行为真   
\-f file     文件为正规文件为真   
\-d file     文件为目录为真   
\-c file     文件为字符特殊文件为真   
\-b file     文件为块特殊文件为真   
\-s file     文件大小非0时为真   
\-t file     当文件描述符(默认为1)指定的设备为终端时为真  

复杂逻辑判断
  
\-a         与   
\-o        或   
!        非  

统计一个文件的中所有的error的占比
  
awk '/error/{err++}END{print err,NR,err/NR\*100&quot;%&quot; }' &lt; xxx.txt 12  

关联数组访问问题

a.txt和b.txt两个文件相同的两个字段(id|money),输出a和b文件中相同id并且b文件money值大的一行
  
cat &gt;&gt;a.txt &lt;&lt;EOF  
  
1|13|35|57|79|9  
  
ROF  

  
cat &gt;&gt;b.txt&lt;&lt;EOF  
  
1|12|23|304|45|56|67|708|89|910|10  
  
EOF  

  
awk -F '|' 'BEGIN{ while(getline &lt; &quot;a.txt&quot;) { user\_map\[$1\] = $2; } }{  
  
if ($1 in user\_map) {if  (user\_map\[$1\] &lt; $2) print $0; }}' b.txt  

注意:如果a.txt不存在,getline会返回-1,导致死循环。我以前曾经碰上过因为这个原因导致程序挂死,所以特别提出来让大家注意

tomcat并发数
  
netstat -an|grep 10050|awk '{count\[$6\]++} END{for (i in count) print(i,count\[i\])'  

sed

sed功能

  
Sed是Strem Editor(流编辑器)缩写,是操作、过滤和转换文本内容的强大工具。常用功能有增删改查,过滤,取行。  
  

参数

  
\-n #取消默认输出  
\-r #使用扩展正则  
\-i #刷到磁盘  
\-e #执行多条sed指令  
\-f #指令放在文件里  

指令

  
a 追加  
i 插入  
d 删除  
c 替换指定的行  
s 替换每一行匹配到的第一个字符  
g 替换每一行的全部  
p 输出  
w 另存文件    
e 执行bash命令  
q 不继续往下读取  

流程

sed 读取文件是逐行读取处理输出

增删改查

单行增加
  
sed '2a 106,dandan,CSO' person.txt  
  
sed '2i 106,dandan,CSO' person.txt  

多行增加
  
sed '2a 106,dandan,CSOn107,bingbing,CCO' person.txt  

例子
  
Port 52113  
  
PermitRootLogin no  
  
PermitEmptyPasswords no  
  
UseDNS no  
  
GSSAPIAuthentication no  
  
  

现在想一条命令增加5行文本到第13行前(地址用逗号分隔的,n1,n2可以用数字、正则表达式、或二者的组合表示)

  
sed -ir '13 i zbcdnPort 52113nPermitRootLogin nonPermitEmptyPasswords nonUseDNS nonGSSAPIAuthentication non#####--end--#######n' /etc/ssh/sshd\_config  

其他例
  • 10{sed-commands} 对第10行操作

  • 10,20{sed-commands} 对10到20行操作,包括第10,20行

  • 10,+20{sed-commands} 对10到30(10+20)行操作,包括第10,30行

  • 1~2{sed-commands} 对1,3,5,7,……行操作

  • 10, s e d − c o m m a n d s 对 10 到最后一行 ( {sed-commands} 对10到最后一行( sedcommands10到最后一行(代表最后一行)操作,包括第10行

  • /oldboy/{sed-commands} 对匹配oldboy的行操作

  • /oldboy/,/Alex/{sed-commands} 对匹配oldboy的行到匹配Alex的行操作

*

  • /oldboy/,${sed-commands} 对匹配oldboy的行到最后一行操作

  • /oldboy/,10{sed-commands} 对匹配oldboy的行到第10行操作,注意:如果前10行没有匹配到oldboy,sed软件会显示10行以后的匹配oldboy的行,如果有1,/Alex/{sed-commands} 对第1行到匹配Alex的行操作

*

  • /oldboy/,+2{sed-commands} 对匹配oldboy的行到其后的2行操作

删除

删除指定的行
  • sed ‘d’ person.txt #删除全部

  • sed ‘2d’ person.txt #删除第二行

  • sed ‘2,5d’ person.txt #删除2到5行

  • sed ‘3,$d’ person.txt #删除3到结尾

  • sed ‘1~2d’ person.txt #删除1,3,5行

  • sed ‘1,+2d’ person.txt #删除1,2,3

  • sed ‘/zhangyao/d’ person.txt #删除匹配的zhangyao行

  • sed ‘/oldboy/,/Alex/d’ person.txt #删除匹配oldboy到Alex行

  • sed ‘/oldboy/,3d’ person.txt #删除从匹配oldboy的3行

打印文件内容但不包含oldboy
  
sed '/oldboy/d' person.txt #删除包含"oldboy"的行  

更改

按行替换c 用新行取代旧行
  
sed '2c 106,dandan,CSO' person.txt #替换第2行的内容  

文本替换s:单独使用,将每一行中第一处匹配的字符串进行替换
  • g:每一行进行全部替换

  • -i:修改文件内容

sed软件替换模型(方框▇被替换成三角▲)
  
sed -i 's/▇/▲/g' oldboy.log  
  
sed -i 's#▇#▲#g' oldboy.log
指定行修改配置文件

指定行精确修改配置文件,这样可以防止修改多了地方。

  
sed '3s#0#9#' person.txt
变量替换
  
x=a  
  
y=b  
  
echo $x $y  
  
sed s#$x#$y#g test.txt
分组替换( )和1的使用说明

sed软件的( )的功能可以记住正则表达式的一部分,其中,1为第一个记住的模式即第一个小括号中的匹配内容,2第二记住的模式,即第二个小括号中的匹配内容,sed最多可以记住9个。

例:echo I am oldboy teacher.如果想保留这一行的单词oldboy,删除剩下的部分,使用圆括号标记想保留的部分。
  
echo I am oldboy teacher. |sed 's#^.\*am (\[a-z\].\*) tea.\*$#1#g'  
echo I am oldboy teacher. |sed -r 's#^.\*am (\[a-z\].\*) tea.\*$#1#g'  
echo I am oldboy teacher. |sed -r 's#I (.\*) (.\*) teacher.#12#g'

命令说明

思路:用oldboy字符替换I am oldboy teacher.

下面解释用□代替空格

  
^.\*am□ –>这句的意思是以任意字符开头到am□为止,匹配文件中的I am□字符串;  
(\[a-z\].\*)□–>这句的外壳就是括号(),里面的\[a-z\]表示匹配26个字母的任何一个,\[a-z\].\*合起来就是匹配任意多个字符,本题来说就是匹配oldboy字符串,由于oldboy字符串是需要保留的,因此用括号括起来匹配,后面通过1来取oldboy字符串。  
□tea.\*$–>表示以空格tea起始,任意字符结尾,实际就是匹配oldboy字符串后,紧接着的字符串□teacher.;  
后面被替换的内容中的1就是取前面的括号里的内容了,也就是我们要的oldboy字符串。  
()是扩展正则表达式的元字符,sed软件默认识别基本正则表达式,想要使用扩展正则需要使用转义,即()。  
sed使用-r选项则可以识别扩展正则表达式,此时使用()反而会出错。  

#####系统开机启动项优化

  
chkconfig --list|grep "3:on"|grep -vE "sshd|crond|network|rsyslog|sysstat"|awk '{print $1}'|sed -r 's#^(.\*)#chkconfig 1 off#g'|bash  
  
chkconfig --list|grep "3:on"
特殊符号&代表被替换的内容#→将1到3行的C替换为–C–
  
sed '1,3s#C#--&--#g' person.txt         #→此处&等于C
批量重命名文件
  
for i in \`seq 5\`;do touch stu\_102999\_${i}\_finished.jpg;done  
  
ls |sed -r 's/(.\*)\_finished(.\*)/mv & 1\_finish2/e'

p 输出指定内容,但默认会输出2次匹配的结果,因此使用n取消默认输出

按行查询
  
sed '2p' person.txt  
sed -n '2p' person.txt  
sed -n '2,3p' person.txt  
sed -n '1~2p' person.txt  
sed -n 'p' person.txt
按字符串查询
  
sed -n '/CTO/p' person.txt  
  
sed -n '/CTO/,/CFO/p' person.txt
混合查询
  
sed -n '2,/CFO/p' person.txt  
  
sed -n '/feixue/,2p' person.txt

特殊情况,前两行没有匹配到feixue,就向后匹配,如果匹配到feixue就打印此行

其他功能

备份功能
  
sed -i.bak '$a 1111111111' xxx.txt  

备份xxx.txt文件为xxx.txt.bak,修改源文件,最后一行添加111111111

另存功能
  
sed 's/sb/SB/g w new.txt' xxx.txt  

把sb替换成SB的整行输出到new.txt中

大小写转换
  
L    #全部转换成小写  
l     #单个转换成小写  
U   #全部转换成大写  
u    #单个转换成大写  
E    #需要和U和L一起使用,关闭U和L的功能  
sed -r 's/(.\*),(.\*),(.\*)/L3,E1,U2/g' xxx.txt
执行多条sed指令
  
sed -e '3,$d' -e 's#10#01#g' xxx.txt  
  
sed '3,$d; s#10#01#g' xxx.txt
打印不可见字符l
  
sed -n 'l' xxx.txt
abc替换ABC(一一对应)
  
tr 'abc' 'ABC' xxx.txt  
  
sed 'y#abc#ABC#' xxx.txt  

可以操作多个文件
  
sed 'y#abc#ABC#' xxx.txt 222.txt  

模拟其他命令
创建svn库的时候自动取消#号和修改路径
  
sed -i -r '12,13s/# //g' svnserve.conf  
sed -i -r '20s/^# (.\*)/1/g' svnserve.conf  
sed -i -r '27s/^# (.\*)/1/g' svnserve.conf  
sed -i -r '12,13s/^# (.\*)/1/g' svnserve.conf  
sed -i -r '32s/# (.\*=)(.\*)/1 /usr/svnData//' svnserve.conf  

一条命令执行(加传参)

  
SvnPath='zhangzhicheng'sed -i -r -e '20s/^# (.\*)/1/g' -e '27s/^# (.\*)/1/g' -e '12,13s/^# (.\*)/1/g' -e "32s/# (.\*=)(.\*)/1 /usr/svnData/$SvnPath/" svnserve.conf  

grep

grep功能

搜索文本,过滤文本字符串 –v取反

选项

参数选项

| 参数选项 |解释说明(带※的为重点) |

| — | — |

| -V|取反,读出指定的内容之外的内容 |

| -A | 打印后面n行的内容 |

| -B| 打印前面n行的内容 |

| -C|打印前后各n行的内容 |

| -n|输出行行号 |

| -E(egrep)|使用扩展正则表达式 |

| -o |只输出匹配到的结果 |

|-i|忽略大小写|

|-a|当grep认为是二进制文件的时候加-a|

基础例子

已知文件 test.txt 内容为xxx 请给出输出 test.txt 文件内容时,不包含 oldboy 字符串的命令。

  
test  
  
liyao  
  
oldboy
  
grep –v oldboy test.txt  

过滤出/etc/services 文件包含 3306 或 1521 两数据库端口的行的内容

  
grep –E “3306|1521” /etc/services  

技巧例子

消除文件空行:

  
grep -v '^$' test.txt  
  
egrep -o "^\[^:\]+" xxx.txt       #匹配开头以非:的行,并输出匹配的内容(-o不是整行输出)  

为了帮助大家更好的学习网络安全,我给大家准备了一份网络安全入门/进阶学习资料,里面的内容都是适合零基础小白的笔记和资料,不懂编程也能听懂、看懂这些资料!

因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取

CSDN大礼包:《黑客&网络安全入门&进阶学习资源包》免费分享

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取

CSDN大礼包:《黑客&网络安全入门&进阶学习资源包》免费分享

  • 23
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值