linux--shell

 

 

 

1. 正则

  正则表达式基本元素包括:普通字符、元字符(如*、^、[]等)

  shell命令如grep、sed、awk使用正则表达式

  1.1 基本的正则表达式

  元字符:

  (1)*

    0个或多个在*字符之前的一个普通字符

    例子:

      hel*o  表示匹配前面的‘l‘字符0次或多次

  (2).

    匹配任意一个字符

  (3)^

    匹配行首,或其后字符的非

    例子:

      ^ab  表示以ab开头的

      ^[0-9] 表示以任意一个数字开头的

      [^0-9]  表示不再范围内的所有字符

  (4)$

    匹配行尾

    例子:

      ^$ 表示空行

      ^.$ 表示只含一个任意字符的行

      ^a[a-z]*c$ 表示以a开头,以c结尾,中间是任意个小写字母字符的字符串

  (5)[ ]

    匹配字符集合

    例子:数字集合、字母集合

      [0123456789]、[0-9]  表示0~9中任意一个数字字符

      [a-z] 表示小写a到z之间任意一个字符

  (6) \

    转义符,屏蔽一个元字符的特殊意义

  (7) \<\>

    精确匹配符号

    例子:

      \<abc\>  只匹配abc这个单词,不匹配包含abc字符的其它串,如不匹配  mabcn   

  (8) \{n\}

    匹配前面一个字符出现n次

  (9)\{n,\}

    匹配前面字符至少出现n次

  (10)\{n,m\}

    匹配前面字符出现n~m次

 

  1.2 扩展的元字符

  (1)?

    匹配0个或1个在其之前的一个普通字符

    例子:

      a?b 匹配ab、aab

  (2)+

    匹配1个或多个在其之前的一个普通字符

  (3) ()和 |

    表示一个字符集合或用在expr中,结合使用表示一组可选的字符

    | 可表示多个正则表达式的或关系

    例子:

      re(a|e|o)d 匹配read、reed、reod

      等同 re[aeo]d

 

  1.3 通配

  shell使用正则表达式中的一些元字符实现通配功能

  (1)*

    任意个的任意字符

    例子:

      *.cpp  表示以任意字符开头,结尾是 .cpp的文件

  (2)?

    表示一个任意字符

    例子:

      a?.cpp  表示以a开头,后面跟一个任意字符,结尾是 .cpp 的文件

  (3)^

    表示取反

  (4)[]

    表示范围内的一个字符

    例子:

      [a-z]*.cpp  表示以a到z开头,后面是任意字符,结尾是 .cpp的文件

  (5){}

    表示一组表达式的集合  或的关系 

    例子:  

      {*.cpp , *.py} 表示所有的cpp文件或py文件

 

  1.4 grep命令

  全面搜索正则表达式,并打印(文本搜索工具)

grep [选项] [模式] [文件...]

  选项:

  -c :只输出匹配字符串的数量

  -i:搜索时忽略大小写

  -h:查询多文件时不显示文件名

  -l:只列出符合匹配的文件名,不列出具体的匹配行

  -n;列出所有的匹配行,并显示行号

  -s:不显示不存在或无匹配文本的错误信息

  -v:显示不包含匹配文本的所有行

  -w:匹配整个单词

  -x:匹配正行

  -r:递归搜索(搜索当前目录和子目录)

  -q:禁止输出任何结果,以退出状态表示搜索是否成功(0:搜索成功; 1:未搜索到满足模式的文本行; 2:命令或程序出错)   

    打印状态: echo $?

  -b:打印匹配行 距文件头部的偏移量,单位 字节

  -o:与-b结合使用,打印匹配的词距文件头部的偏移量,单位字节

  -E:支持扩展的正则表达式

  -F:不支持正则表达式,按字符串的字面意思进行匹配

 

  模式:用双引号或单引号括起来,表示要搜索的字符串或用正则表达式

    搜索正则的元字符如搜索 *、. 要转义

    - 也要转义

  例子:

  (1)在当前目录下的所有.c和.h文件里面搜索以‘#‘开头的行,并显示行号

grep -n ^# *.c *.h

 

  (2)在当前目录的*.c文件里搜索以5个 - 符号开头的文本行 (- 符号也要转义)

grep -n ^\-\{5\} *.c

 

  

  POSIX增加的字符类:

    [:upper:]  表示[A-Z]

    [:lower:]  表示[a-z]

    [:digit:]    表示[0-9]

    [:alnum:]  表示[0-9a-zA-Z]

    [:space:]  表示空格或Tab

    [:alpha:]  表示[a-zA-Z]

    [:cntrl:]   表示ctrl键

    [:graph:]或[:print:]  表示ASCII码33~126之间的字符

    [:xdigit:]  表示16进制数字[0-9A-Fa-f]

 

 

2. sed命令

  2.1  sed命令使用

(1)sed是一个非交互式文本编辑器,可对文本文件、标准输入进行编辑(标准输入可以是来自键盘输入、文件重定向、字符串、变量、管道的文本)。

  从其中读取数据复制到缓冲区,然后读取命令行或脚本的第一个命令,对此命令要求的行号进行编辑并重复执行,直到命令行或脚本中所有命令执行完毕  

  使用场景:①编辑相对交互式文本编辑器而言很大的文件

       ②编辑命令太复杂,在交互式文本编辑器中难以输入

         ③对文件扫描一遍,但是需要执行多个编辑函数

  效果:sed是对缓存区中复制来的文件副本进行操作,不影响原文件,要保存修改的内容,需要将输出重定向到另一个文件

sed  sed命令  file1 > file2    将file1中文件执行sed命令,并保存到file2

 

(2)

  ①在shell中输入命令调用sed

sed [选项]  sed命令  操作文件

  ②在脚本中写sed命令,通过sed命令调用

sed [选项] -f sed脚本文件  操作文件

  ③脚本中写sed命令,直接执行该脚本文件

./sed 脚本文件 操作文件

 

  操作文件如果没有指定,则默认是标准输入

  选项:

  -n:不打印所有的行到标准输出

  -e:将下一个字符串解析为sed编辑命令,如果只传递一个编辑命令给sed则-e可省略(每一个编辑命令前都要加-e)

  -f:正在调用sed脚本文件

 

(3)定位文本、编辑命令

  定位文本:指定行号或通过正则匹配

  x:第x行

  x,y:从x到y行

  /pattern/:查询包含模式的行

  /pattern/pattern/:查询包含两个模式的行

  /pattern/,x:从与模式匹配的行到x行之间的行

  x,/pattern/:从x行到匹配行之间的行

  x,y!:查询不包括x和y行的行

 

  编辑命令:即具体做什么操作(前面没有-)

  p:打印匹配行

  =:打印文件行号

  a\:在定位行号之后追加文本信息

  i\:在定位行号之前插入文本信息

  d:删除定位行

  c\:用新文本替换定位文本行,是替换整个行

  s:使用替换模式替换相应模式,替换字符串,而不是整个行

  r:从另一个文件中读文本

  w:将文本写入到另一个文件,后面要跟新文件名

  y:变换字符

  q:第一个模式匹配完成后退出

  l:显示与八进制ASCII码等价的控制字符

  {}:在定位行执行的命令组

  n:读取下一个输入行,用下一个命令处理新的行

  h:将模式缓冲区的文本复制到保持缓冲区

  H:将模式缓冲区的文本追加到保持缓冲区

  x:互换模式缓冲区和保持缓冲区的内容

  g:将保持缓冲区的内容复制到模式缓冲区

  G:将保持缓冲区的内容追加到模式缓冲区

 

  2.2 sed命令使用例子

(1)打印某文件的第一行到标准输出

  只打印第一行,则编辑命令为 ‘1p‘ ,不打印其他行,要加上sed命令的选项 -n

sed -n 1p a.sb

  linux--shell

   如果不加-n选项呢,则先打印第一行,再打印整个文件内容

 

(2)多个编辑命令

  匹配以a开头,中间是其他小写字母或空格,以c结尾的行,先打印行号,再打印行的内容(第5行、6行)

sed -n -e /^a[a-z ]*c$/= -e /^a[a-z ]*c$/p a.sb

  linux--shell

 

 

(3)用脚本形式

  在行6后面追加一些内容

#!/bin/sed -f
6a\ 
a new line \   #在行6下一行添加此行内容  \ 换行
another new line  #又添加一行

  执行脚本:添加可执行权限,再对该文件执行此脚本

chmod u+x append.sed
./append.sed a.sb

  linux--shell

 

 

(4)匹配元字符

  如果要查找 * . $ - 等字符,要转义 \*

  如:查找打印含 - 字符的行

sed -n /\-/p a.sb

  linux--shell

 

 

(5)通过元字符/正则匹配

  $ 字符在正则中表示行结尾,在sed命令中表示 最后一行

  如:打印最后一行

sed -n $p a.sb   #打印最后一行
sed -n $p a.sb    #打印最后一行

  linux--shell

 

  

  打印行5到结尾行:

sed -n 5,$p a.sb

  linux--shell

 

 

(6)整行替换与字符串替换

  c\新文本  和 s/匹配串/新串/[替换选项]

  原内容:

  linux--shell

 

  对ab进行两种替换:

sed /ab/c\hahahaha a.sb    #含 ab的行被替换为hahahaha

  linux--shell

 

 

sed s/ab/hahahaha/ a.sb    #将ab字符串替换为hahahaha

  linux--shell

 

 

  串s替换的选项:s/被替换串/新串/[替换选项]    前面没有-

    g:替换文本行中所有出现被替换字符串的地方,而不是该行首先出现匹配的地方

    p:与-n选项结合,只打印替换行

    w 文件名:将输出定向到一个文件

  替换时特殊字符:&  表示被替换字符串

    例,要给串123前后假设*号   s/123/*&*/g  

 

(7)变换字符

  sed ‘y/被变换的字符序列/变换后的字符序列/‘ 输入文件

  将被变换字符序列中字符逐个用变换字符序列中字符替代

  例:将某文件中a变成A,b变成B,c变成C

sed y/abc/ABC/ a.sb

  linux--shell

 

 

 

(8)其他用法

  ①处理匹配行的下一行

 

  ②sed缓冲区处理

 

 

 

3. awk编程

  3.1 awk编程模型

  awk程序由一个主输入循环维持(此循环由awk框架实现),主输入循环自动一次读取输入文件行以供处理,我们再添加处理文件行的动作(即不需要我们写main、不需要打开文件、读取文件、关闭文件,只需要写处理文件行的内容就行了)

  

  特殊字段:

    BEGIN:在主输入循环之前执行

    END:在主输入循环之后执行

 

  3.2 awk调用

  ①shell

awk [-F 域分隔符] awk程序段 输入文件

  ②awk调用脚本文件

awk -f awk脚本文件 输入文件

  ③直接执行可执行文件

./awk脚本文件 输入文件

 

   3.3

  awk语句由模式和动作组成。模式是一组用于测试输入行是否需要执行动作的规则,动作是包含语句、函数、表达式的执行过程

  awk支持?、+两个扩展元字符

  awk视输入文件是格式化的文件

 (1)awk记录和域

  awk将每个输入文件的定义为记录,行中每个字符串定义为域(域之间用空格、tab、其他符号间隔)

  用 $ 指定执行动作的域,每条记录域从 $1 开始(而$0表示所有的域,即整行)

  ①域操作符 $ 后可以跟数字、也可是是变量、变量表达式

awk BEGIN{a=1;b=2} {print $(a+b)} a.sb  //即print $3

  ②改变域间隔符

  空格是默认间隔,tab视作连续空格

awk -F"," print $2 a.sb       #一种是通过-F选项修改

 

awk BEGIN {FS=","} {print $1,$2} a.sb   #通过环境变量FS指定域分隔符

 

  FS可通过正则表达式设置域分隔符

 

  (2)关系和布尔运算符

  linux--shell

  布尔:

    逻辑或: ||

    逻辑与:&&

    逻辑非:!

 

  (3)条件和循环语句

  条件里面可以写正则,语句和C类似

  if   if/else   if/else else  

  while(条件表达式)  {动作}

  do {动作}  while(条件)

  for(设置计数器初值;测试计数器;计数器变化) {动作}

  (4)表达式

  表达式由数值、字符常量、变量、操作符、函数、正则表达式组合而成

  变量:字符串值、数值类型  

  算术运算符:

  linux--shell

 

 

  (5)系统变量

  一种用于改变awk的默认值,如FS修改域分隔符;一种用于定义系统值,处理文本时可读取,如域数量、记录数、文件名,是动态的。 

  linux--shell

 

 

  (6)格式化输出

  printf (格式控制符,参数)

  格式控制符:修饰符、格式符

  linux--shell

 

  linux--shell

 

 

  (7)内置字符串函数

  linux--shell

 

  linux--shell

 

   如替换gsub,不带第三个参数时,作用于整个行(行中所有域);第三个参数指定作用的域

 

  (8)向awk脚本传递参数

./awk NUM=3 FS="," a.sb   #  = 号两边不能有空格

 

  (9)数组 

  格式类似C,但awk数组不需要定义数组类型和大小,可直接赋值后使用

  数组是关联数组

    数组的索引可以是数字,但该数值与数组存储地址无关

    访问数组:for (variable in array) {对array[variable]的动作}

    in的用法:判断array[index]是否在数组中(返回1或0)  index in array

 

  两个数组形式的系统变量:

    ARGV:命令行参数  个数是ARGC,参数从ARGV[0]到ARGV[ARGC-1]

    ENVIRON:环境变量    

  两个打印命令行参数和系统变量的示例脚本:

  脚本1:

#!/usr/bin/awk -f
BEGIN {
    for (x=0;x<ARGC;x++)
        print "arg" x ":" ARGV[x]
}

  执行: 并传入数个参数

  linux--shell

 

 

  脚本2:

#!/usr/bin/awk -f
BEGIN {
    for (i in ENVIRON)
        print i "=" ENVIRON[i]
}

  执行效果:

  linux--shell

 

 

 

 

  3.4 例子

  linux--shell

 

(1)判断空行

awk /^$/{print "a blank line"} a.sb

  输入文件有一个空行,就打印一行字符串

  linux--shell

 

 

(2)查看 /etc/passwd文件中注册名为root的用户信息

awk BEGIN {FS=":"} $1~/root/ /etc/passwd

  $1后面,  ~ 匹配正则

  linux--shell

 

(3)if条件判断

  如果域2大于等于56,就打印正行

awk {if($2>=56) print $0} a.sb

  linux--shell

 

(4)判断某文件有多少空行

  在遍历行时,如果匹配到空行,变量加1,在所有行结束后(END),打印此变量的值

awk /^$/{n++} END{print n} a.sb

  linux--shell

  注意: /^$/{n++;} 条件和执行语句之间不能是换行,见(7)

 

(4)计算此文件第三列数字的平均值

  注意本文件有一个空行,因此是第三列数字相加除以3;也要注意如果为空文件或全是空行的情况,打印 empty

awk !/^$/{total += $3;n++} END{if(n>0) print total/n;else {prin"empty"}} a.sb

  linux--shell

 

 

awk !/^$/{total += $3;n++} END{if(n>0) print total/n;else {prin"empty"}} b.sb

  linux--shell

 

 

(5)计算第三列数字的平均值 

  如果有一些行数据不合法,比如不是空行但没有第三个域,或者第三个域不是数字,则要加上条件:  

  写法1:在表达式里面加if条件

awk !/^$/{if(!(NF<3) && ($3~/[0-9]+$/)){total += $3;n++}} END{if(n>0) print total/n;else {print "empty"}} a.sb

  注意,if后面要执行的语句要用{}括起来

  写法2:在遍历行时就判断,在内部表达式内只要toal和n的操作,这样更清晰

awk (!/^$/)&&(NF>=3 && $3~/[0-9]+$/){total += $3;n++} END{if(n>0) print total/n;else {print "empty"}} a.sb

 

   linux--shell

 

 

(6)向awk脚本传递参数

  test.awk脚本文件内容:打印域的数量不是传入参数个数的行

#!/usr/bin/awk -f
NF !=NUM {print $0}

  执行:

./test.awk NUM=3  FS=" " a.sb

  linux--shell

 

 

 (7)一个注意的地方【计算空行数量】

  文件改为有两个空行,如下图:

  linux--shell

 

 

  脚本1:

#!/usr/bin/awk -f
/^$/
{
    n++;
}

END {
    print n;
}

  执行效果:

   linux--shell

 

   

   脚本2:

#!/usr/bin/awk -f
/^$/{
    n++;
}

END {
    print n;
}

  执行效果:

  linux--shell

 

 

  awk是每调入文件的一行,就对其执行一遍脚本文件,而脚本文件估计是以换行符和{} 区分语句块。对于脚本1, /^$/ 表示打印空行,而后面的 n++ 则对每一行都调用一次,因此结果为7;

  

--------

grep:用于搜索

sed:用于修改、编辑文本文件中某些行,也可用于搜索

awk:访问文本文件,操作某些数据,用于搜索和统计计算

---------

 

4. 文件操作的一些命令

  4.1 sort

   类似awk,sort将文本看作多条记录,每条记录有多个域

  sort [选项] [输入文件]

  linux--shell

 

 

  4.2 uniq

 

  4.3 join

 

  4.4 cut

 

  4.5 paste

 

  4.6 split

 

  4.7 tr

 

  4.8 tar

 

5. 关于变量和引用

 

6. 结构

 

7. I/O重定向

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  

 

linux--shell

上一篇:windows下VirtualBox的Linux获取主机串口(USB转串口)


下一篇:处理器是如何调度进程的?