LINUX系统高级应用

【过滤大log文件】
  #!/bin/bash
  for X in $(egrep -o "[A-Z]\w*Exception" log_week.txt | sort | uniq);
  do
    echo -n -e "processing $X\t"
    grep -c "$X" log_week.txt
  done
  其中:
    egrep -o 找出日志文件中出现在“Exception”字眼之前的文字,对他们排序去重
    "[A-Z]\w*Exception" 用于定位Exception的正则模式
    log_week.txt 大log文件
    | sort 排序
    | uniq 去重
    for X in $(...); 针对前面生成的异常列表中的每个异常循环执行代码
    echo -n -e "processing $X\t" 执行中输出
    grep -c "$X" log_week.txt 在大log文件中找出这个异常出现的次数

【Crontab】
  1.格式 :
    M  H  D  m  w  cmd
      第1列M表示分钟1~59,为 * 时表示每分钟都要执行,为 a-b 时表示从第 a 分钟到第 b 分钟这段时间内要执行
      第2列H表示小时1~23(0表示0点)为 */n 时表示每 n 小时个时间间隔执行一次
      第3列D表示日期1~31,为 a, b, c,... 时表示第 a, b, c,... 日要执行
      第4列m表示月份1~12
      第5列w表示星期0~6(0表示星期天)
      第6列cmd要运行的命令,程序被送入sh执行,这个shell只有USER,HOME,SHELL这三个环境变量
    停止发信:
      程序在执行后,系统会发email给相应用户,若不希望收到信,请在每一行空一格之后加上 “> /dev/null 2>&1” 即可
  2.例子 :
    #每月的4号与每周一到周三的11点重启
    0 11 4 * mon-wed /usr/local/etc/rc.d/lighttpd restart
    #在 12 月内, 每天的早上 6 点到 12 点中,每隔3个小时执行一次 /usr/bin/backup :
    0 6-12/3 * 12 * /usr/bin/backup
    #每月每天的午夜 0 点 20 分, 2 点 20 分, 4 点 20 分....执行 echo "haha"
    20 0-23/2 * * * echo "haha"
    #晚上11点到早上8点之间每两个小时,早上8点
    0 23-7/2,8 * * * date
    #每个月的4号和每个礼拜的礼拜一到礼拜三的早上11点
    0 11 4 * mon-wed date
  3.Crontab并发冲突
    有冲突:1 * * * * /usr/bin/rsync -avlR /data/files    172.16.xxx.xxx:/data
    无冲突:1 * * * * flock -xn /var/run/rsync.lock -c ' rsync -avlR /data/files    172.16.xxx.xxx:/data'
      -x参数指定锁文件,-n参数指定如果锁文件已经存在就等待。-c参数指定建锁成功后运行后面的命令。只要第一个flock进程没执行完,锁文件都会存在,就不会运行第二个rsync进程。
  4.CentOS里安装crontab:
    yum install vixie-cron
    yum install crontabs
    service crond start

【find命令】
  -type 按文件类型查找 d目录,f文件,l链接:-type d
  -user 按用户查找:-user root
  -perm 按文件权限查找:-perm 755
  -regex 按正则表达式查找:-regex '.*b.*3'
  -amin 按访问时间查找,精确到分钟:-amin -5#找5分钟内访问过的,-amin +5#找5分钟以外访问过的
  -atime 按访问时间查找,精确到天:-atime -5#找5天内访问过的,-atime +5#找5天以外访问过的
  -mtime 按修改时间查找,精确到天:-mtime -5#找5天内修改过的,-mtime +5#找5天以外改过的
  -maxdepth 限定查找路径深度
  -size 按尺寸查,尺寸有c字节,k,M,G:-size +10000c找10000字节以上的
  -exec 执行命令/-ok 同-exec,每个操作都会让用户确认
  -print find ./ -mtime +3 -print | xargs rm -f –r
  【删除修改时间在3天以上的文件】# find . -ctime +3 -exec rm -rf {} \;
  【过滤出符合关键字的文件并删除之】# find /dir -type f -exec grep keyword {} \; -print -exec rm {} \;
  【dos2unix批量转】# find -type f | xargs dos2unix -o
  【找出扩展名是小写mp3的文件,拼成rm -rf “filename.ext”的格式】# find . -name "*.mp3" -printf "rm -rf \"%p\"\n" | sed -n -e "s:\.\\::gp" > rmfile.sh
  【找出扩展名是大写MP3的文件,并生成去掉文件名前4个字符的脚本,执行改名操作后清除临时文件】
    # find . -name "*.MP3" -printf "ren \"%p\" \n" | sed -n -e "s:\.\\::gp" > oldfile.txt
    # find . -name "*.MP3" -printf "\"%p\" \n" | sed -n -e "s:\.\\....::gp" > newfile.txt
    # paste oldfile.txt newfile.txt > renfile.sh
    # chmod 0777 renfile.sh
    # ./renfile.sh
    # rm -rf oldfile.txt newfile.txt renfile.sh
  【查找比某个时间早的文件】
    # touch -t 12071200 oldfile
    # find /var/www/html -newer oldfile -print
    # find /var/www/html/ -path “/var/www/html/_node” -prune -newer oldfile -print
  【删除文件大小为0的文件】
    # find ./ -size 0 -exec rm {} \;
    # find ./ -size |xargs rm -f &
    # rm -i `find ./ -size 0`
  【一次解压多个.tar.gz文件】# find ./ -name ‘*.tar.gz’ -exec tar zxvf {} \; -print

【du命令】
  1.想看当前目录下所有目录以及子目录的大小:
    # du -h .
      -h表示用K、M、G的人性化形式显示
  2.只想看当前目录下abc目录的大小,并不想看其他目录以及其子目录:
    # du -ch abc | tail -n 1
      -c表示最后计算出所有所列目录的大小之和
    # du -sh abc#汇总查看目录的大小
      -s表示汇总
    # du -h –max-depth=0 abc
      –max-depth=n表示只深入到第n层目录
  3.列出abc目录及其子目录下所有目录和文件的大小:
    # du -ah abc
      -a表示包括目录和文件
  4.列出所有abc目录中的目录名不包括xyz字符串的目录的大小:
    # du -h –exclude=’*xyz*’
  5.想在一个屏幕下列出更多的关于abc目录及子目录大小的信息:
    # du -0h abc
      -0(杠零)表示每列出一个目录的信息,不换行,而是直接输出下一个目录的信息。

  【lsof 列出打开的文件】
    # lsof abc.txt 显示开启文件 abc.txt 的进程
    # lsof -i :22 知道 22 端口现在运行什么程序
    # lsof -c nsd 显示 nsd 进程现在打开的文件
    # lsof -g gid 显示归属 gid 的进程情况
    # lsof +d /usr/local/ 显示目录下被进程开启的文件
    # lsof +D /usr/local/ 同上,但是会搜索目录下的目录,时间较长
    # lsof -d 4 显示使用 fd 为4 的进程
    # lsof -i [i] 用以显示符合条件的进程情况
    # lsof -i[46] [protocol][@hostname|hostaddr][:service|port]
      46 –> IPv4 or IPv6
      protocol –> TCP or UDP
      hostname –> Internet host name
      hostaddr –> IPv4 位置
      service –> /etc/service中的 service name (可以不止一个)
      port –> 端口号(可以不止一个)
      例子:

    # lsof -p 12 # 看进程号为 12的进程打开了哪些文件
【sed流文本处理】
  1.参数
    -n 除非是明确表明要输出的行,否则不输出。一般会和-p配合使用,输出那些发生变化的行。
    -f 设定包含command的文件名称
    -e 执行命令,命令分为两部分,一是确定范围,二是处理方式。
      确定范围:可以指定行数:例如3,5表示第3-5行;5,$表示第5行至末行;也可用模式匹配:例如/^[dD]/匹配行首不是以d或D开头的行。
      处理方式:
        d 表示删除匹配的行
        = 表示打印行号
        p 打印匹配的行
        r 读取指定文件的内容
        w 写入到指定文件中
        a\ 在下面插入新行新内容
        i\ 在上面插入新行新内容
        c\ 更改当前行
        n 调入匹配行的下一行
        y/old/new/ 对当前行执行替换操作
        执行多个命令:1.可以在命令之间使用分号,2.用多个-e
        一个地址多个命令
          有时,可能要指定应用到一个地址的多个命令。这在执行许多 's///' 以变换源文件中的字和语法时特别方便。要对一个地址执行多个命令,可在文件中输入 sed 命令,然后使用 '{ }' 字符将这些命令分组,如下所示:
          1,20{     s/[Ll]inux/GNU\/Linux/g     s/samba/Samba/g     s/posix/POSIX/g }
          上例将把三个替换命令应用到第 1 行到第 20 行(包括这两行)。还可以使用规则表达式地址或者二者的组合:
          1,/^END/{         s/[Ll]inux/GNU\/Linux/g         s/samba/Samba/g         s/posix/POSIX/g     p }
  2.例子
    【模式匹配】
      sed -n -e "s:huodong\/\(.*\)\/\(.*\)\.\(.*\):hd_\1_\2\.\3:g;s:\/: :g;s:\?: :g;p"
    【格式转换】
      UNIX -> Windows 系统
        # sed -e 's/$/\r/' myunix.txt > mydos.txt
      DOS格式的文本转换成UNIX格式
        # sed -e 's/.$//' dos.txt>unix.txt
    【删除】
      删除每行最后的两个字符
        # sed 's/..$//' test  (用sed '/..$/d' test为什么不行?/..$/表示匹配所有末尾含有两个字符的行)
      删除每一行的前两个字符
        # sed ’s/..//’ test
      过滤掉#打头的行
        # sed -n -e 's/^[^#]/&&/gp' filename.ext
    【按单词反转行】
      # sed -e '1!G;h;$!d' forward.txt > backward.txt
        foo bar oni -> oni bar foo
        说明:'1!G':'1G'表明'G'命令只应用于第一行,多了'!'则忽略该行,'G'命令将应用到除第一行之外的所有行。
        '$!d' 命令与之类似。'$d'只把 'd'命令应用到文件中的最后一行,有了'!'之后,将把 'd' 命令应用到除最后一行之外的所有行。
        'h'命令告诉 sed 将模式空间(保存正在处理的当前行的缓冲区)的内容复制到保留空间(临时缓冲区)。然后,执行 'd' 命令从模式空间中删除 "foo"。
        第二行:在将 "bar" 读入模式空间之后,执行 'G' 命令,该命令将保留空间的内容 ("foo\n") 附加到模式空间 ("bar\n"),使模式空间的内容为 "bar\n\foo\n"。'h' 命令将该内容放回保留空间保护起来,然后,'d' 从模式空间删除该行。
        对于最后的 "oni" 行,除了不删除模式空间的内容(由于 'd' 之前的 '$!')以及将模式空间的内容(三行)打印到标准输出之外,重复同样的步骤。
    【用模式来定位行范围】
      # sed -n ‘/2005/,/2007/p’ mysed.txt
      用/2005/来匹配行范围的首行,用/2008/来匹配行范围的最尾行。只要遇到符合要求的行尾即停止。
    【读取一个特定文件的内容,将其插入到本文件指定的地方】
      # sed ‘/2005/r ins.txt’ mysed.txt
    【将符合条件的行写入到文件中】
      # sed ‘/200[4-6]/w new.txt’ mysed.txt
    【对匹配行的下一行进行处理】
      # sed ‘/2004/{n;y/eijng/EIJNG/;}’ mysed.txt
      # sed ‘/200/{n;y/eijng/EIJNG/;}’ mysed.txt #你可以发现,BEIJING是隔行出现的。
    【sed交换任意两行】
      # sed -n '2!{p;d};h;n;:1;8!{N;b1};G;h;n;p;g;p' (无法交换相邻行)
      # sed -n '4!{p;d};4!{h;n;:1;4!{N;b1};G};h;n;p;g;p'
      # sed '2{:a;N;9{s/\(^[^\n]*\)\(.*\)\(\n\)\([^\n]*$\)/\4\2\3\1/;t};ba}'
      # sed -n 'A{h;n;x;H;x};p' (只交换相邻行)
      # sed -n 'A{h;n;B!{:a;C!{N;ba};x;H;n};G};p'

【一个程序的输出接到两个程序的输入】
  如果想要把一个程序的输出接到两个程序的输入,单靠 | 是不成的:
    # mkfifo /tmp/fifo
    # prog2 < /tmp/fifo &
    # prog1 | tee /tmp/fifo | prog3
  这就会把prog1 的标准输出同时给 prog2 和 prog3 的标准输入。
  这里mkfifo是创建一个命名管道,这样可以有多个管道使,tee 则会把输出同时输出到一个文件和标准输出,实现了分岔。prog2 < /tmp/fifo & 这里要加个 &,不然管道里没数据 prog2就会阻塞。
  【用diff比较两个命令的输出】
    # mkfifo /tmp/fifo1
    # mkfifo /tmp/fifo2
    # ls dir1 > /tmp/fifo1 &
    # ls dir2 > /tmp/fifo2 &
    # diff /tmp/fifo1 /tmp/fifo2

【把一个字符串翻转】
  # echo “abcdefg” | perl -lne ‘{$a = reverse($_); print $a;}’
  # echo bottle|rev

【awk】
  【过滤掉#号打头的行,和所有的空行】# awk ‘/^[^#]/&&/^[^$]/’ filename > new.file
  【查看文件的第一列】# awk -F : ‘{print $1}’ /etc/passwd
  【统计排序】# awk -F 't' '{print $4}' file.ext | grep keyword | uniq -c | sort -rn | head -10
    其中:
      awk -F '\t' 将file.ext文件,用TAB分割,打印第4列
      grep keyword 只列出符合keyword的行
      uniq -c 汇总计数
      sort -rn 按数值排序
      head -10 取%C

猜你喜欢

转载自fangrn.iteye.com/blog/807756