美文网首页
Linux文本处理三架马车之二 awk

Linux文本处理三架马车之二 awk

作者: 陈宇乔 | 来源:发表于2018-12-09 23:44 被阅读0次

    参考https://www.cnblogs.com/irockcode/p/6700135.html

    范例

    $ echo "Linux" | awk '{printf "|%-15s|\n",$1}'
    
    |Linux     |
    

    说明:对于echo命令的输出,Linux是经管道发给awk。printf函数包含一个控制串。百分号让printf做好准备,它要打印一个占15个格、向左对齐的字符串,这个字符串夹在两个竖杠之间,并且以换行符结尾。百分号后的短划线表示左对齐。控制串后面跟了一个逗号和$1。printf将根据控制串中的格式说明来格式化字符串Linux。

    范例

    $ echo "Linux" | awk '{printf "|%15s|\n",$1}'
    
    |          Linux|
    

    说明:字符串Linux被打印成一个占15 格、向右对齐的字符串,夹在两个竖杠之间,以
    换行符结尾。

    image.png

    实战项目备份

    cat 1| awk '/FFG/{printf"%s\t%s_TUMOR\n",$1,$2}'
    
    image.png

    awk处理“列”

    参数
    awk [option] 'BEGIN{初始代码} {循环代码} END{最后代码}' filename

    运算符
    || 逻辑或
    && 逻辑与
    ~ ~! 匹配正则表达式和不匹配正则表达式

    说明书

    充分了解awk

    第一: 自定义分隔符 -F

    示例:

    awk -F : '{print}' /etc/passwd
    # 以冒号为分隔符,打印每行
    awk -F : '{print $0}' /etc/passwd
    # 等同于awk –F: '{print}' /etc/passwd
    awk -F : '{print $1}'  /etc/passwd
    # 以冒号为分隔符,打印每行的第一个字段
    awk  -F : '{print "root"}' /etc/passwd
    # 以冒号为分隔符,每行都打印root
    awk -F : '{print $1"\t"$3}' /etc/passwd
    # 以冒号为分隔符,打印每行的1、3字段,\t表示tab,默认时空格
    

    第二: 理解 -v

    -v var=value 自定义变量

    awk -v test='hello gawk' '{print test}' /etc/fstab
    # 这里自定义了test
    

    第三:理解FS,OFS 和RS,ORS

    FS 和 OFS 可以看做是字段分隔符
    awk -v FS=':' '{print $1,FS,$3}' /etc/passwd
    # 以冒号为输入字段分隔符,打印1、:、3字段
    awk -v FS=':' -v OFS='-' '{print $1,$3,$7}' /etc/passwd
    # 以冒号为输入字段分隔符,以----为输出字段分隔符,打印1、3、7字段
    
    
    RS 和 ORS 可以看做是换行符
    awk -v RS=' ' -v ORS='###' '{print$1,$2}' /etc/passwd
    # 以空格为输入记录分隔符,以###为输出记录分隔符,打印每行
    awk -v RS=' ' '{print$1,$2}' /etc/passwd
    # 以空格为输入记录分隔符,碰到空格就换行,打印每行
    

    awk实战代码

    # 在gtf文件的第一列的N前加入ref| 
    cat ref_GRCh38.p12_top_level.gff3 |grep -v '^#' |awk 'BEGIN{FS='\t';OFS='\t'}{gsub(/^N/,"ref|N",$1);print $0}' 
    # 在gtf文件的第一列的最后加入| 
    cat ref_GRCh38.p12_top_level.gff3_step1 |grep -v '^#' |awk 'BEGIN{FS='\t';OFS='\t'}{gsub(/$/,"|",$1);print $0}' 
    

    打印除了第一行列的所有列

    cat ref_GRCh38.p12_top_level.gff3 |head -50|grep -v '^#' |awk '{for(i=2;i<=NF;++i) printf $i "\t";printf "\n"}'
    

    第五步整理好注释信息

    zcat ref_GRCh38.p12_top_level.gff3.gz |grep -v '#'|cut -f 9|awk '/gene_biotype/{print $0}'|awk -F ';' '{for(i=1;i<=NF;i++){if($i ~/^gene_biotype=/){print $i}}}' |awk -F '=' '{print$2}'  >gene_type
    ## 找到有gene_biotype的行,并将这一行中的以gene_biotype=为开头的列找出来
    zcat ref_GRCh38.p12_top_level.gff3.gz |grep -v '#'|cut -f 9|awk '/gene_biotype/{print $0}'|awk -F ';' '{for(i=1;i<=NF;i++){if($i ~/^gene=/){print $i}}}' |awk -F '=' '{print$2}'  >gene_name
    paste gene_name gene_type >NCBI_ID_trans.txt
    

    awk 玩转NCBI下载下来的gff文件

    awk 包含

    cat patient_info.txt |awk '/FFG/{printf "%s_tumor\t%s\n",$2,$4}' > tumor_config
    cat patient_info.txt |awk '$0~"blood|BC"{printf "%s_normal\t%s\n",$2,$4}' > normal_config
    

    常用代码

    awk 有个类似的查找功能//

    history |awk '/prefetch/{print $0}'
    
    echo 1 2 3| awk '{ print "total pay for", $1, "is", $2 * $3 }'
    

    awk -F #-F相当于内置变量FS, 指定分割字符

    cat /etc/passwd |awk  -F ':'  '{print $1"\t"$7}' 
    cat /etc/passwd |awk  -F ':'  'BEGIN {print "name,shell"}  {print $1","$7} END {print "blue,/bin/nosh"}'
    awk '{count++;print $0;} END{print "user count is ", count}' /etc/passwd
    awk -F ':' 'BEGIN {count=0;} {name[count] = $1;count++;}; END{for (i = 0; i < NR; i++) print i, name[i]}' /etc/passwd
    awk '$3 == 0 { print $1 }' emp.data
    awk '$3 >0 { print $1, $2 * $3 }' emp.data
    awk '$3 > 15 { time = time + 1 } END{ print time, "s" }'
    awk 'NF != 3     { print $0, "number of fields is not equal to 3" }'  # 与 && , 或 || , 以及非 !
    awk '$2 < 3.35   { print $0, "rate is below minimum wage" }'  # Eg: !($2 < 4 && $3 < 20)
    awk 'END { print NR, "employees" }'
    
    awk     '{ pay = pay + $2 * $3 }
    END { print NR, "employees"
          print "total pay is", pay
          print "average pay is", pay/NR
        }'
    
    

    实战

    将1-3,分别改为A-B

    cat $1 |while read id 
    do
        arr=(${id})
        pre_name=${arr[0]}
        after_name=${arr[1]}
        mv ${pre_name} $after_name
    done
    
     bash chang_name.sh ./tmp
    
    将1-3,分别改为A-B

    查找

    cat patient_info |awk '/FFG/{printf "%s_tumor\t%s\n",$2,$4}' > tumor_config
    cat patient_info |awk '$0~"blood|BC"{printf "%s_normal\t%s\n",$2,$4}' > normal_config
    

    awk

    cat tumor_config |awk '{print$2}'|awk -F '_' 'BEGIN{FS='_';OFS='_'}{for(i=1;i<=(NF-2);i++){printf "%s_", $i}; printf "\n"}'
    # 改进
    cat tumor_config |awk '{print$2}'|awk -F '_' '{for(i=1;i<=(NF-2);i++){printf "%s_", $i}; printf "\n"}' |awk '{sub(/_$/,"")}1' >tumor_config_2
    
    cat normal_config |awk '{print$2}'|awk -F '_' '{for(i=1;i<=(NF-2);i++){printf "%s_", $i}; printf "\n"}' |awk '{sub(/_$/,"")}1' >normal_config_2
    

    这个时候printf 占主导,所有OFS 没有差别

    删除最后一个字符
    sed 's/.$//'
    awk '{sub(/.$/,"")}1'
    awk '{printf $0"\b \n"}' ufile
    

    关于正则表达式的运用

    目的删除红色部分

    image.png image.png
    less colume1 |sed -r 's/_.*\.sort/\.sort/' 
    

    .* 代表了任意字符

    我自己傻傻的解决方式
    # cat colume1 | awk '{gsub(/\_L4\_[a-z][0-9]/,".",$0);print$0}'
    # cat colume1 |awk '{gsub(/_L4_*/,"",$0);print$0}'
    # cat colume1|sed -r 's/\_L4\_*sort//g'
    ls M* >colume1
    
    cat colume1|awk -F '.sort' '{print$2}' >colume3
    cat colume1|awk -F '.sort' '{print$1}' >colume2
    
    cat colume2 |awk '{gsub(/\_L4\_....../,"",$0);print$0}' >colume4
    # . 表示任意字符
    paste colume4 colume3|awk '{printf"%s%s\n",$1,$2}' > final_colume
    paste colume1 final_colume >config
    
    vim rename.sh
    cat $1| while read id 
    do
        arr=($id)
        filename=${arr[0]}
        newfile=${arr[1]}
        mv $filename $newfile
    done
    
    bash rename.sh ./config
    

    相关文章

      网友评论

          本文标题:Linux文本处理三架马车之二 awk

          本文链接:https://www.haomeiwen.com/subject/gkelhqtx.html