• awk中引用shell变量执行替换的脚本


    遇到问题:
    现在有两个脚本,我想
    将file1中的内容按file2来匹配
    [root@154 home]# cat file1
    3-1-1 POTV=1,POTA=0,POTP=2
    1-4-76 POTV=1,POTA=0,POTP=1
    2-1-2 POTV=1,POTA=1,POTP=1
    3-1-4 POTV=1,POTA=1,POTP=2
    4-1-5 POTV=1,POTA=1,POTP=2
    7-1-2 POTV=1,POTA=1,POTP=2
    3-1-10 POTV=1,POTA=1,POTP=2
    1-1-1 POTV=1,POTA=2,POTP=0

     

    [root@154 home]# cat file2
    1-1-1
    2-1-2
    2-1-3
    3-1-4
    4-1-5
    

      

    相当于grep的精确匹配,不过是用awk实现的
    grep -w '1-1-1' file1
    实现用for in循环取值,赋予变量
     
    写了一个替换思路用for in循环将匹配内容变为变量,然后匹配替换
    for i in `cat file2`
    do
    awk  '$1==''"'$i'"''{print $0}' file1 >> urfile
    done
     
    awk  '$1=='   '"'   $i   '"'    '{print $0}'   file1
    这段中单引号是脱义的作用
    在awk中精确匹配字符,需要将字符用双引号引用: 即 awk '$1=="1-1-1"{print $0}' test 所以对传递参数要用单引号将双引号脱义让awk识别
    单引号成对出现是按就近原则来的

      

    这里需要注意的是,这里引用的'$1=='   '"'   $i   '"'    '{print $0}'里面不能有空格,不然会发生语法错误

    (猜想大概是因为IFS分段原因,awk被分成了几段话,造成语法错误)

    [root@154 home]# cat aemployee.txt 
    101 John Doe,CEO
    102 Jason Smith,IT Manager
    103 Raj Reddy,Sysadmin
    104 Anand Ram,Developer
    105 Jane Miller,Sales Manager
    [root@154 home]# awk '$1==''"'101'"''{print $0}' aemployee.txt 
    101 John Doe,CEO
    [root@154 home]# awk '$1==' '"'101'"''{print $0}' aemployee.txt 
    awk: cmd. line:1: $1==
    awk: cmd. line:1:     ^ unexpected newline or end of string
    

      这里就能看出来,应该跟我猜的一样,如果有不对,请大神指点

    2017/07/01更新:

    之前的方法太蠢了,改进下,因为之前实验失败,所以认为这样是不行的,不过发现好像是之前实验错误:
    awk '$1=="'$i'"{print $0}' file1 >> urfile

    ===================================================================

    新需求

                其中file1只有270行,
                 file2有345行,
                 file1的第一列内容都包含在file2中
                 这是两个文件的关系
    要求:
          我想以file2为样本,将file1第一列匹配file2行进行替换

    即file2的第一行为
    1-1-1
    在file1中存在
    1-1-1 POTV=1,POTA=2,POTP=0
    然后将file2中内容替换为file1中该行内容(或者添加file1中第二列内容)
    即变成以下样子
    1-1-1 POTV=1,POTA=2,POTP=0
    1-1-2
    1-1-3
    1-1-4
    1-1-5

    -------------------------------------------------------------------------

    自己编了一个脚本,毕竟没有基础,大神莫笑

    脚本1

    #!/bin/bash
     
     
    for i in `cat yrsd`
    do
            s=`awk  '$1==''"'$i'"''{print $0}' test`
            if [ "$s" == "" ];
                    then echo "$i" >>1
            else
                    echo "$s" >>1
            fi
    done
    

     脚本2

    	#!/bin/bash
    
    
    	for i in `cat yrsd`
    	do
    		echo $i
    		if [ -z "$(awk  '$1==''"'$i'"''{print $0}' test)" ];
    			then echo "$i" >>1
    		else
    			echo "$(awk  '$1==''"'$i'"''{print $0}' test)" >>1
    		fi
    	done
    

      

     
    既然已经实现了awk替换,那加个判断就能搞定
    另外,大神给的方法
     
    awk 'FNR==NR{a[$1]=$2;next}{$2=a[$1];print}' file1 file2
    

      解释一下这个吧,这是使用了awk的内置变量NF和FNR,利用这两个变量,结合数组,先将需要替换的内容组合放到数组里,供匹配使用;

      再使用了next这个内置函数模块,这样的话就可以达到先将内容放到数组里,然后执行匹配替换。

      这里还有一个精彩的地方,在file2文件里,并没有$2这栏,而在执行的时候使用了不存在的$2;

      开始我也疑惑,后来想到,这是一个类似于赋值的方法,原本不存在$2被赋值为替换的内容;

      打印该列,print后不接参数等同于print $0

     
    使用awk的FNR与NR的区别,利用数组,一条命令搞定
    这里的知识点还是挺多的,看我这篇分析吧,讲的更详细
  • 相关阅读:
    Json对象和Json字符串
    主界面的构造函数报错
    WPF DataGrid绑定的数据源更新后界面信息不更新
    WPF 数据绑定 ( 经验 )
    WPF 简单快速地去掉Button控件的边框
    字节数组与字符串形式的数字(序列号)之间的相互转换
    将十进制数字转换为字节数组
    WPF 调用线程无法访问此对象,因为另一个线程拥有该对象。
    cmd中一些命令
    Notepad++运行快捷键的设置
  • 原文地址:https://www.cnblogs.com/irockcode/p/7004004.html
Copyright © 2020-2023  润新知