欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

sed和awk简介

程序员文章站 2022-04-18 13:29:19
...

Sed简介

sed [-nefr] 动作:该指令可以将输入的数据进行处理后输出到标准输出,利用sed处理后的结果不会影响到原输入流,比如sed '1,5d' filePath将会把文件filePath的第15行删除后再进行标准输出,但是这不会影响到文件filePath,处理可以是取代、删除、插入等。

   参数:

      -n:表示使用安静模式,sed默认会将处理后的所有行都打印出来,加上参数-n后就只有经过处理的行才会显示出来。

      例如:

      sed -n '1,5p' filePath,该指令将会只打印出filePath这个输入的15行,而没有加-n的话会先在输出filePath15行之后再把整个filePath内容都输出。

      -e:后面接动作,当后面只有一个动作的时候可以把-e省略。

      例如:

      1.sed -e '1,5d' filePath,该指令表示将filePath的第15行删除后再进行输出,因为sed后只进行了一个动作,所以-e参数也可以省略变成sed '1,5d' filePath

      2.sed -e '1,5d' -e '8ihello' filePath,该指令表示将filePath的第15行删除,然后在第8行插入hello,之后再进行标准输出,因为这里是同时进行两个动作,所以参数-e是不能省略的

   扩展:

   1.同时执行多个动作的时候也可以使用分号“;”来进行分隔,这样上面的命令可以利用分号变成sed '1,5d;8ihello' filePath

   2.当要在同一行上执行多个动作的时候还可以用大括号“{}”包起来,如sed -n '1,5{=;p}' filePath表示文件filePath的第15行需要执行两个动作,第一个动作“=”是打印出当前行的行号,第二个动作“p”是打印出当前行。

      -f:后面接一个文件的完整路径,这种情况是我们把需要执行的动作写在一个文件里面,然后利用sed -f filePath来执行

        例如:

        sed '1,5d' filePath改成使用-f的方式,先建立一个文件,假设为cmdFile,把命令放入该文件中,则cmdFile的内容为1,5d,这里面的命令是不需要用单引号包起来的,然后以后调用的时候就可以这样调用:sed -f cmdFile filePath,出来的效果和sed '1,5d' filePath是一样的。

      -r:使用该参数表示该sed使用的正则表达式支持延伸型正则表达式,预设是基础正则表达式语法

   动作:[n1[,n2]function]

      n1n2表示多少行到多少行(sed提供两种方式定位行,一种是数字,一种是正则表达式),当只有一个行的时候表示的就是代表的那一行,n1n2也可以使用正则表达式来进行选取,例如/hello/d则表示将包含hello的那一行找出来并删除,还可以使用$表示最后一行,例如sed '5,$d' filePath表示将文件filePath的第5行到最后一行的内容都删除然后进行标准输出

      /pattern1/,/pattern2/:表示满足pattern1那行到满足pattern2的那一行

      /pattern1/,5:表示满足pattern1那行到第5

      3,5!:表示不包含35行的其他的行

      function有以下几种:

        a:表示新增,后面接的内容将出现在指定行的下面,例如sed '5ahello' filePath将在文件filePath的第5行后面添加一行,即为第6行内容为hello,而sed '3,5ahello' filePath则将在文件filePath的第3到第5行每一行的后面都添加一行内容为hello的行

        i:表示插入,后面接的内容将插入到当前行,而当前行的内容将依次往后移,例如:sed '5ihello' filePath表示在文件filePath的第5行插入一行,内容为hello,然后原来的第5行将往下移动变为第6行,依此类推

        c:表示取代,是针对行而言的,后面接的内容将取代指定行的内容,例如:sed '3,5chello' filePath表示将文件filePath的第35行用hello取代

        d:表示删除,例如:sed '3,5d' filePath表示将文件filePath的第35行删除后再进行标准输出

        p:表示进行打印,例如:sed '3,5p' filePath表示将文件filePath的第35行的内容打印出来

        r:表示读取文件内容到指定行的下面

        w:表示把指定行的内容写入到指定文件

        s:表示取代,是针对每一行的内容而定的,例如:sed 's/hello/world/g' filePathsed '3,5s/hello/world/' filePath, 表示将文件filePath里面的每一行中出现的hello都替换为world,如果最后没有加上参数g表示只会替换每一行的第一个匹配的hello,在匹配的替换值中可以使用“&”来代表当前匹配的值,如:sed '3,5s/hello/00&/g' filePath,由于”&“符号代表当前匹配到的值,所以该语句的意思就是将filePath35行的hello都替换为00hello

   注:除了可以使用参数g之外,还可以使用以下参数:

      数字参数,使用数字参数表示匹配到的指定第几个才替换;

      参数p,使用参数p表示将替换的行进行打印出来,参数p需要与-n一起使用才能将替换的那一行打印出来,如:sed -n 's/hello/world/p' filePath

      参数w,使用参数w表示将替换的行写到指定的文件,如:sed 's/hello/world/w outputFile' filePath

      q:表示退出,当执行完指定的行之后就退出,如:sed '5 q' filePath,表示执行到第5行之后就退出,因为sed默认会进行打印操作,所以这句的意思是打印到5行之后就退出。

      y:表示字符变换,是针对单个字符进行的,如:sed '1,5y/12345/abcde/' filePath表示将filePath文件15行内容中的1替换为a2替换为b...5替换为e

      l:字母L命令可以用于显示内容中的特殊字符,如退格键等,如:sed 'l' filePath

      nn命令可以处理匹配行的下一行,如:sed '/hello/{n;s/123/321/g}'表示把包含hello字符串那一行的下一行中的123全部替换为321

       

       

Awk简介

awk [-F 分隔符] 'awk程序段' 输入文件:awk命令是用来把文件中每一行分成各个域来进行处理,预设的分隔符是空格键或者[tab],分割成的域会一次放入$1$2...$n等变量中,而$0则代表一行。与sed相似,awk也可以使用-f参数表示调用awk脚本文件

   awk由模式和动作组成,模式pattern决定了动作何时执行,模式一般就是正则表达式,awk支持“?”和“+”两个扩展元字符,而sedgrep是不支持的

   awk 'pattern{动作}' file,动作是需要放到大括号{}里面的,如:awk '/01/{print $0}' test,表示将文件test中包含01的行打印出来

   awk中内置的变量有:

      FS:表示分隔符,在设置分隔符的时候也可以不使用-F参数,而是在BEGIN中指定FS的值

      NR:表示当前执行的是第几行

      NF:表示当前行被分隔成几个域

      ARGC:表示当前awk命令的参数数量

      ARGV:是数组形式,表示当前awk命令的参数,ARGV[0]awkARGV[1]一般是文件名

        如:awk '{print $1}' inputFile,则ARGC2ARGV[1]inputFile

      OFS:输出的域之间的分隔符,默认是一个空格

      ORS:输出的记录之间的分隔符,默认是一个换行符

      RS:输入文件按照什么分隔记录,默认是换行符

   awk还可以使用awk -v var=val 'awk程序段' 输入文件,这样的形式来进行变量的申明与使用,使用-v申明和赋值的变量是可以在BEGIN语句段里面使用的,而直接接在awk程序段后面申明的变量是不能在BEGIN语句段里面使用的。

   awk还可以使用模式匹配来进行行的选择,如:awk -F":" '$2>5' test,表示把文件test中的每一行按照“:”进行分隔,把分隔后第2个变量的值大于5的行选出

   awk支持进行行的选择的模式有以下这些:

      >  大于

      == 等于

      <  小于

      >= 大于或等于

      <= 小于或等于

      != 不等于

      ~  匹配正则表达式,如:awk -F":" '$1~/hello/' test,表示把文件test按照":"进行分隔后,把第1个变量中包含hello的行选出

      !~ 不匹配正则表达式

   上面的这些模式也可以用来跟条件判断IF语句一起使用,如:awk -F"\t" '{if($1>5 && $2~/hello/) print $0}' test表示将test文件中的每一行按照tab键进行分隔,然后选出第一个域大于5并且第2个域包含hello的行

   awk中主要有3个语句段,一个是BEGIN,一个是MAIN,一个是ENDBEGIN语句段会在执行awk的主语句段之前执行,END语句段会在执行awk主语句段之后执行

      示例,使用BEGINMAINEND来计算文件的总行数:awk 'BEGIN{sum=0}{sum++}END{print "Sum:",sum}' test,由这个示例可以看出,在awk中定义的变量在使用时是不需要加上"$"dollar符号的。

   awk中内置的字符串函数:

      gsub(a,b) 表示将输入文件中的a替换为b,返回值是替换的个数

      gsub(a,b,c)  表示将c中的a替换为b,这里的c一般代表的是一个域,返回值是替换的个数

      index(s,t) 返回字符串s中第一个t出现的位置

      length(s) 返回字符串s的长度

      split(a,b,c) 将字符串ac为分隔符进行分割,分割后保存在数组b中,函数的返回值是分割后域的数量。

        如:echo "Hello,World" | awk '{print split($0,words,",");for(var in words) print words[var]}'

      match(s,t) 测试s是否包含匹配t的字符串,若匹配则返回匹配字符ts中第一次出现的位置,若不匹配则返回0

      sub(r,s,t) t中第一次出现的r替换为s,返回值是替换的个数

      sub(r,s)  将每一行中第一次出现的r替换为s,返回值是替换的个数

      substr(r,s)  返回字符串r中从s开始之后的字符串

      substr(r,s,t)   返回字符串r中从s开始长度为t的字符串15602232321 525345

      注:关于这些函数还可以这样使用:

        awk 'sub("A","B"){print $0}' file,表示将file中每一行的第一个A替换为B,如果替换了就将该行进行打印。

   awk脚本传递参数,方法是:

      awk 脚本 parameter=value 输入文件,示例:awk '{print num}' num=2 inputFile,该语句将根据inputFile的行数打印多个数字2

      awk脚本传递的参数不能在BEGIN语句段中使用,这是因为BEGIN语句段是一开始就执行的,这时候参数值还没有进行传递。

   awk内部的语法跟C语言类似,它里面也支持条件IF语句和循环语句whiledo whilefor,还有switch case语句,当满足某个条件需要进行多个动作时需要用大括号把多个动作包起来。

      if语句的语法:

        if (条件判断1)

           动作1

        else if (条件判断2)

           动作2

        else

           动作3

      if中的条件判断也可以使用“~”符号和正则表达式进行判断,如:

        if ($0~/hello/)

           print $0

        上面的语句表示如果该行包含hello字符串就将该行进行打印

      while语句的语法:

        while(条件判断)

           动作

      do while语句的语法:

        do

           动作

        while(条件判断)

      for语句的语法:

        for(初值;判断;变化)

           动作

        如:awk '{for(i=1;i<=NF;i++) print $i}' inputFile

   awk还支持数组,该数组的索引值可以为任意值,awk都会把它以键值对的形式进行储存,可以使用for(var in array)的形式对数组内容进行循环,也可以使用if (key in array)判断array中是否有以key为键值的键值对存在,可以使用delete删除数组中的一个元素或者删除整个数组,如:delete array[key]则会删除array中以key为索引的元素,要删除整个数组的时候,就直接使用delete 数组名,如:delete arrayName

      示例:

        awk 'BEGIN{data[1]=1;data[hello]="hello"}{if("1" in data) print "exist element 1."}' inputFile

   awk还支持多维数组,如:

      awk 'BEGIN{

        nums[0][0] = 0

        nums[0][1] = 1

        nums[0][2] = 2

        nums[0][3] = 3

        nums[1][0] = 1

        nums[1][1] = 2

        nums[1][2] = 3

        nums[1][3] = 4

        for (var1 in nums) {

           for (var2 in nums[var1]) {

              print nums[var1][var2]

           }

        }

      }{}' fileName