'使用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 "port\tservice"} {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/\(......\)\(.*\)\(...\)$/\1\3/'
Hello ou.
  第一个域......        表示连续6个字符串
  第二个域.*    表示任意多个字符串
  第三个域...    表示$最后三个连续字符
  \1\3     表示打印第一个和第三个域
  
注意:一般特殊的字符可以采用"[ ]"进行转义。比如转义. $ /等使用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