自学shell编程——第5讲(正则表达式+grep、sed、awk的使用)

自学shell编程——第5讲(正则表达式+grep、sed、awk的使用)

这是shell编程语言,python语言重点的部分。比较好理解,但是难应用,要多多练习,有时候会事半功倍。
grep、sed、awk这三个命令,是对文本处理的三剑客。也多与RE共同使用,必须要掌握。以实现更加复杂的字符串操作。但是各有不同擅长。

  1. grep用于匹配一定要求的字符串
  2. awk和sed多用于处理表格式字符串。awk擅长处理表格中的列。sed擅长表格中的行。

注意:下面的内容写的是我常用的,如果详细学习,请自行查阅其它资料

1. 正则表达式RE

  1. RE本质上是特殊符号组成的一个式子,帮助你模糊查询
  2. 可以用到RE的地方很多,常见的命令有grep。当然,在某些情况下也可以用。比如,你想删除这个目录下,所有以.sh结尾的文件。你可以使用rm *.sh。
  3. grep标准使用格式:** grep 正则表达式 寻找对象文件 参数 。这样查找的结果会直接输出到终端,你后面可以使用 管道符(|) 对查找结果进行操作或者 定向符(>或者>>) **将查找结果输出到特定文件。
  4. grep参数。-H:将你查询的文件对象,输出到匹配到的每一行的前面。
    -n:打印匹配行号,输出到匹配到的每一行的前面
    -w:全字匹配
    这些参数,你要自己试一试,方便更好理解
    自学shell编程——第5讲(正则表达式+grep、sed、awk的使用)_第1张图片
  5. 正则表达式的特殊字符表
    自学shell编程——第5讲(正则表达式+grep、sed、awk的使用)_第2张图片
    这里只是将常用的字符列了出来,大家可以自行练习熟悉,其中要注意** 转义字符的重要性 **。
grep '^0[0-9]\{2,3\}[ -][0-9]\{8,9\}$' file.txt > newfile.txt  #在file.txt中寻找符合RE的行,并输出到newfile.txt中

该RE表示:①以数字0开头;②0-9中任意数字重复2次或3次,即随机生成2位或3位数;③空格或者-任选一个(这里可能出现多个连续空格情况);④0-9中任意数字重复8次或9次;⑤$:表示结束

2. awk命令的使用。

  1. awk的工作次序是:首先读取file,txt文件的一行,然后根据’’(单引号)内的指令进行工作,然后再对下一行进行相同工作,此来类推。
  2. 打印文档的指定列。awk ‘{print $1,$5}’ file.txt。打印文档的第一列和第五列。若是$0则表示整行
  3. 过滤。awk ‘$5==11 && $6>=90 {print $0}’ file.txt。先对该行的第5列和第6列的值进行判断,如果满足则输出该行,反之跳过。
  4. 打印表头,需要引入内建变量NR。awk ‘NR==1 || $6>=90 {print $0}’ file.txt。NR是一个内建变量,表示已经读出的行数(即行号)。如果行号为1或者第6列的值大于90,则输出该行,反之跳过。
  5. 使用** 正则表达式匹配字符串 。awk '$0~/Brown/ {print}’ file.txt。将包含Brown的行输出。* ~ 波浪号后面一对斜杠内的写入正则表达式,表示在$0整行进行该RE的匹配**
    ** 这里整理了一些常用内建变量 **
    $0 当前记录,该行所有内容
    $1 ~ $n 当前记录的第1到第n列的内容
    FS 输入字段间的分隔符,默认为空格或Tab。这里会简写-F
    OFS 输出字段的分隔符,默认是空格
    NF 当前记录中的字段个数,就是有多少列
    NR 行号,从1开始。如果有多个文件,该值会进行累加。有些文件第一行是表头,判断有可能会出错,需要注意。
    FNR 当前记录数,与NR不同,不同文件重新记数,不累加。
    RS 输入的记录分隔符,默认为换行符
    ORS 输出的记录分隔符,默认为换行符
    FILENAME 当前输入文件的名字

3. sed命令的使用

这里这些一些我常用的sed命令,更详细的内容,请自行查阅资料。

  1. 输出某一特定行信息。sed -n ‘3p’ file.txt 输出第3行。
  2. 输出特定区间行信息。sed -n ‘2,5p’ file.txt 输出第2到第5行内容。
  3. sed命令的参数
    -n 输出匹配的行信息,不修改原文件内容
    -i 对原文件中匹配信息进行操作,会修改原文件内容
  4. 最重要的部分。sed对正则表达式的处理。
    sed ‘s/year/years/’ file.txt #将file.txt文件每行的第1个year改成years,将结果输出到屏幕,不修改file.txt文件
    sed ‘2s/year/years/’ file.txt #将file.txt文件的第2行的第1个year改成years,将结果输出到屏幕,不修改file.txt文件
    #$ ,表示结束
    sed ‘2,$s/year/years/’ file.txt #将file.txt文件的第2到最后一行的第1个year改成years,将结果输出到屏幕,不修改file.txt文件
    sed ‘2,5s/year/years/’ file.txt #将file.txt文件的第2到第5行的第1个year改成years,将结果输出到屏幕,不修改file.txt文件
    #-i,对原文件进行修改
    sed -i ‘2,5s/year/years/’ file.txt #将file.txt文件的第2到第5行的第1个year改成years,将结果输出到屏幕,并修改file.txt文件
    #g,对所有匹配结果进行修改
    sed -i ‘2,5s/year/years/g’ file.txt #将file.txt文件的第2到第5行的所有year改成years,将结果输出到屏幕,并修改file.txt文件
    #2,对第2个匹配结果进行修改
    sed -i ‘2,5s/year/years/2’ file.txt #将file.txt文件的第2到第5行的第2个year改成years,将结果输出到屏幕,并修改file.txt文件
    #2g,对第2个及以后的匹配结果进行修改
    sed -i ‘2,5s/year/years/2g’ file.txt #将file.txt文件的第2到第5行的第2个及以后的year改成years,将结果输出到屏幕,并修改file.txt文件

如果同时要做多个正则匹配。你可以分开写也可以合在一起写。大佬就喜欢合在一起写,然后看着很复杂,何必呢!!!

sed 's/year/years/;3,$s/.$//' file.txt
sed -e 's/year/years/' -e '3,$s/.$//' file.txt

就是分开看。用;(分号)表示分隔。①s/year/years/:将每行的第1个year改为years。②3,$ s/.$//:将第3到最后一行的末尾字符去除

你可能感兴趣的:(shell学习,生物信息学,bash)