'使用sed 去除以空格开头的行,第一个sort进行整理输出,uniq -c进行统计,sort -rn进行从大到小排列 # cat cat.ip | awk -F "|" '{print $1}' | sed "s/ //g" | sort | uniq -c | sort -rn 3 192.168.2.2 3 192.168.2.12 2 192.168.2.14 2 192.168.2.13 1 192.168.2.16 1 192.168.2.15 统计一个文本内每个单词出现的次数(xargs将字符串分段截取-n1表示一一个字段) # cat hello | xargs -n1 | sort | uniq -c # cat hello | awk '{for(i=1;i<=NF;i ) {print $i}}' | sort | uniq -c(可以实现相同的效果, awk '{for(i=1;i<=NF;i ) {print $i}}'会循环打印每一行) 2 andy 2 hello 1 mac 1 meizu 1 world 2 world! 1 xxb 2 yangwa 注意:如果在脚本里面使用for(());do done循环 好像if(())也是这样子滴 确定字符串的长度:(awk,expr) # cat hello | awk '{print length}' 打印每一行的字符长度(算之间的空格) #(expr length "$hello") 注意:hello是一个字符串变量 awk执行子串抽取操作; #(expr substr "$hello" 4 5) 截取字符串的4-9字符串 #cat hello | awk '{print substr($1,2,3)}' 从第一个字段里面打印第二个字符3个长度子串 substr(string,子串的第一个字符所在位置,子串的字符数) 使用sed执行简单查找和替换: # echo $hello | sed -e "s/y/xxb/g" #grep -v ^# ntp.conf 过滤配置文件中注释的行 #sed "s/#.*//g" ntp.conf 将配置文件中的#开头所有用空格代替(也可以实现上述功能) 但是上述两个都有弊端,就是输出有很多空格 sed awk实现过滤空行和注释行; #sed "s/#.*//g" ntp.conf | awk '{if(length !=0) print $0}' 只打印非空行 sed双查找和替换以及过滤行: #sed "/xxb/s/he/she/g" hello 先匹配xxb的行,找到he全文替换she #cat hello | sed "1d" 删除第一行.删除前三行"1,3d" 使用grep查找多个字符串: #pgrep -l sshd 查看sshd的所有进程(格式:PID 服务名) 其他参数 -o 显示终止程序的PID -n显示开始的PID egrep是过滤多个字符串的命令,和grep用法一般 #egrep "xxb|ntp|rpcbind" /etc/passwd 过滤多个字符串 使用grep过滤进程表:(使用grep过滤进程最后也会出现grep进程) # ps aux | grep [s]sh # ps aux | grep ssh | grep -v grep awk进行列求和: # ll | awk '{T =$5} END {print T}' T =$5 执行第五列相加(去掉END将打印每一次相加) 注意:awk中有两个特别的规则,BEGIN和END,他们允许定制处理在主输入循环之外发生,处理之前和之后都可以。在本例中使用END规则表示总计处理已经完成,awk应该转移到后继继续处理。 # cat 1 | awk 'BEGIN {print "porttservice"} {print $5"t"$3}' awk生成随机数列: awk中的rand()函数可以产生0-1之间的随节数字,srand()函数使用传递给它作为参数的种子值初始化随机数字产生器。 #echo | awk '{srand(); print int(100 * rand())}' 产生1-100整数随机数字 使用shell中本身自带的随机数生成器(RANDOM),不可控制的 #echo $RANDOM 产生0-32767之间的数字 awk非常善于显示被空格或者特定分隔符分开的域。从未知的串中抽取特定字符或者连续字符更具有挑战。这时其实使用sed就更有特色了。 使用sed显示基于字符的域: 可以使用sed基于字符模式而不是基于域来进行字符串分隔。模式描述了将要分隔中的元素。这些元素用圆括号中包含一个或者多个(.)来表示,一个点表示单个字符。当字符串被分隔之后,模式中的每一个元素相当于输入串中的一个域。 (.):一个字符 (.*):任意多个字符 (...):三个连续的字符,通常有多少个. 就表示多少个连续的字符。 分隔指令是有前斜线分开的之前和之后两部分指令组成。第一部分是模式,第二部分指定了域或者将要显示串所在的域。当sed被调用时,包括模式在内的整个分隔指令用单引号引上,模式中的圆括号用反斜线转移() # echo $hello | sed 's/(......)(.*)(...)$/13/' Hello ou. 第一个域...... 表示连续6个字符串 第二个域.* 表示任意多个字符串 第三个域... 表示$最后三个连续字符 13 表示打印第一个和第三个域 注意:一般特殊的字符可以采用"[ ]"进行转义。比如转义. $ /等
使用grep从一个模式匹配中返回末尾行: 和正则表达式一起运行grep可以很容易的从标识的文件或者输出中获取某些行. # cat /etc/passwd | awk '$1 ~ /^daemon/ {getline;print $1;}' 打印以daemon开头行的下一行(如果想打印后面几行可以getline;print $1) adm:x:3:4:adm:/var/adm:/sbin/nologin # cat /etc/passwd | awk '$1 ~/bash$/ {getline;print $1;}' 打印行尾bash的下一行和最后bash结尾的行 bin:x:1:1:bin:/bin:/sbin/nologin xxb:x:500:500::/home/xxb:/bin/bash
使用grep返回模式匹配之前的行: # awk '/sshd/{print pNR,p0}{pNR=NR;p0=$0}' /etc/passwd 第一个命令在文件中查找模式串,当处理文件中的每一行内容时,分别在变量p0和pNR中存储匹配行之前的一行和该行的记录数(awk的内部变量NR表示当前输入行中的记录数)。当查找到包含匹配串的某一行时,显示其之前行的记录数(pNR)和之前行自身(p0) 使用ed进行简单的查找和替换: #ed -s /etc/ntpd.conf << EOF (EOF是分隔符,) >g/server/s/server/xxb-andy/g >w 保存 >q 退出 >EOF 这样就成功替换了ntpd.conf中的server部分 #ed -s /etc/ntpd.conf < ed.script (也可以把修改部分写在脚本) g/server/s/server/xxb-andy/g 第一g表示全局globle,指示ed命令对整个目标文件执行查找和替换,如果没有只替换一行 第一server表示在整个目标文件中查找的项 s表示告诉ed查找第四个元素 第四个元素是第二个查找条件,限定了再次查找的范围为满足第一个查找项的范围 最后g表示全局替换 # ed -s /etc/hosts << EOF 查找到目标IP,替换localhost为xxb-andy > g/127.0.0.1/s/localhost/xxb-andy/g 可以使用正则表达式的^和$哦! > w > q > EOF 统计目录下的当前文件总数,并进行定时汇总: #!/bin/bash FileDR="/usr/share/doc/db4-devel-4.7.25/examples_c:10:15:root" for monitor in $FileDR //变量可以是整个FileDR中 do set - `echo $monitor | sed 's/:/ /g'` //使用空格将FileDR分隔成几个域 file_count=` ls $1 | wc -l` //只能统计当前目录下的文件个数 if [ $file_count -lt $2 ] //判断当前阈值(10表示警告阈值,15最大值,root为邮件发送用户) then contuine elif [ $file_count -ge $2 -a $file_count -lt $3 ] then echo "Warning:File count in $1 is $file_count,should be less than $2" | mail -s "Directory file count warining for $1" $4 else echo "Error:File count in $1 is $file_count,shoule be less than $2" | mail -s "Directory file count error for $1" $4 fi done 注意:这样只能查找当前目录下的文件,却无法查看子目录里面的文件个数,使用find命令查看处理大批量的文件 find方式是最快的;其次是echo *;ls命令比较费时间
/proc报告 /proc文件系统,它为当前运行系统提供了虚拟视图,传统的proc文件系统附着在/proc安装点上,但并不是一个真正的文件系统,其目录下的很多文件大小都为0.包含了很多的当前系统运行的很多信息。浏览这些文件时,他们从内核的角度给出系统信息,他们的内容基于系统资源和特性,如内存、cpu等网络利用情况 以一系列数字为名字的目录代表当前进程的PID,这些目录的文件涉及到被调用的命令、执行环境、传递给命令的参数、内存使用情况、以及其他价值的进程信息。
口令老化通知(定时修改用户口令) #
date 的格式: #date " %F %Y %m %d %A" %F显示:年-月-日(2014-9-29) %Y显示:年(2014) %m显示:月(9) %B显示英文的月份 %d显示:日(29) %A显示:周几(Monday) %a表示(Mon) %c显示:详细的年月日
新增加系统环境变量: #export PATH=/bin:$PATH 然后再bin下的可执行文件就可以当系统命令使用
系统内部环境变量的作用: $0 给出程序完成路径和程序名称 $# 给出程序参数的总个数 $? 给出程序的退出值0为正常,其他为不定错误 $* 给出所有的参数 $$ 进程的PID $! 进程的后台ID 注意:变量的饮用一般使用双引号""
从键盘读入变量值: #read hello 将键盘输入的数字赋值到hello #!/bin/bash echo "请出入数字名:" read x y z=`expr $x $y` 注意:在做算法的时候变量和符号之间需要空格 echo $z
字符串的比较:(=、!=、-n、-z字符串是否相等,不相等,大于零,等于零) #!/bin/bash read x y [ "$x" = "$y" ] echo $?
函数的定义:计算两数之和 #!/bin/bash ab(){ a=$1 注意:这块定义参数只能使用数字<$y出现错误> b=$2 z=`expr $a $b ` (z=`expr $a * $b`) echo "a b="$z (echo "a*b="$z) } ab $1 $2 echo $# 输出参数个数 echo $$ 输出当前PID echo $0 输出当前脚本名称以及路径
脚本中调用脚本,其实就是将自己的脚本加入到当前的环境中,然后使用./触发,当成所谓的系统命令。(export PATH=/root:$PATH)
fold命令:限制文件列宽。fold -w 3 hello 补充:fold指令会从指定的文件里读取内容,将超过限定列宽的列加入增加字符列后,输出到标准输出设备,若不指定任何文件名,或是给予的文件名为-,则fold指令会从标准输入设备读取数据 tr命令:字符翻译设备,主要用于大小写的转换。cat hello | tr [a-z] [A-Z] join命令:将sort后的文件的相同部分联合。join hello hello1 将两个文件中相同部分的文字结合起来输出到终端
shell脚本实际说来就是用于系统管理和文件操作用的,能够方便自如的处理大量重复性的工作。
简单的循环脚本:某目录下有m1-4.txt,写一个脚本创建m1-4目录,并将相应的文件拷贝进去 #!/bin/bash mkdir m{1..4} 批量创建文件和目录的正则.. for((i=1;i<=4;i )) do mv m$i.txt m$i done
使用for循环做累加; for((i=2;i<=9;i )) do sum=`expr $sum $i` //sum=$(($sum $i)) echo $sum 输出每一项求和 done echo $sum 输出累加和 shell内部的运算方式; for((i=1;i<=9;i )) do sum=$(($sum $i)) //注意,如果写成$i $sum就会不识别$sum默认为0 echo $sum done echo $sum