免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3442 | 回复: 7
打印 上一主题 下一主题

[文本处理] 关于 AWK的修改字段值 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-07-09 15:35 |只看该作者 |倒序浏览
各位大侠们, 我想写个小程序,需要对重复的文本的某一个字段修改,消除重复,例如:

111;222;333;
111;222;333;
111;222;333;
111;222;333;
111;222;333;
111;222;333;
111;222;333;

修改成

111;222;333;
111;222;334;
111;222;335;
111;222;336;
111;222;337;
111;222;338;
111;222;339;

把第三个字段修改成递增的,想把文件名和要修改的列数作为2个参数传进去,现在可以固定修改某个字段,但是动态传进去总是弄不好,脚本如下:
#!/bin/ksh
#change file  -  Change specific field for duplicat records


if [ $# != 2 ]
then
        echo "param is not correct"
        exit 1
fi

inputfile=$1
fldnum=$2

if [ ! -s $inputfile ]
then
        echo "${inputfile} not found or size is 0"
        exit 1
fi

outputfile=./output
echo "" > $outputfile

prev=0
curr=0
i=0

while read line
do
        echo "read from file: $line"

        if [ -z $line ]
                then continue
        fi       
       
        curr=$line
        if [ $prev != $curr ]
        then       
                i=0
                prev=$curr
        fi
       
        tmp=`echo $line|cut -d';' -f$fldnum`
        export        tmp=`expr $tmp + $i`       

        echo "After plus, tmp: $tmp"
       
        export fldvar="\$$fldnum"
        echo "fldvar: $fldvar"

        chgline=`echo $line|awk -F';' -v OFS=';' '{ENVIRON["fldvar"]=ENVIRON["tmp"]}1'`
       
        echo "after change: $chgline"
       
        echo $chgline >> $outputfile

        i=`expr $i + 1`

done < $inputfile


上面的  

        chgline=`echo $line|awk -F';' -v OFS=';' '{ENVIRON["fldvar"]=ENVIRON["tmp"]}1'`

想把  ENVIRON["fldvar"] 作为动态的字段值,比如 $2,$3,但总是不成功,请教各位大虾??

论坛徽章:
0
2 [报告]
发表于 2013-07-09 16:01 |只看该作者
回复 1# nizainade

http://bbs.chinaunix.net/forum.p ... st%3D1%26digest%3D1

    3. Awk怎么引入变量?
有两种方法:
<1>: awk -v var=$VAR '{code}'
<2>: awk '{CODE}'$VAR'{CODE}'
例如:
VAR=XXX

awk -v var=$VAR 'BEGIN{print var}'
XXX

awk 'BEGIN{print "'$VAR'"}'
XXX
复制代码
我推荐使用第一种方法,这样可以避免一些不必要的烦恼。如http://bbs.chinaunix.net/thread-1835620-1-1.html



还有。下面不是很简单

awk -vOFS=';' -F';' '{print $1,$2,$3+NR-1}'  file

论坛徽章:
71
15-16赛季CBA联赛之同曦
日期:2018-08-23 15:41:42辰龙
日期:2014-08-15 09:07:43狮子座
日期:2014-06-03 13:55:33亥猪
日期:2014-06-02 11:17:08巨蟹座
日期:2014-05-06 10:02:03午马
日期:2014-05-04 08:18:27亥猪
日期:2014-04-29 11:11:32技术图书徽章
日期:2014-04-24 15:51:26技术图书徽章
日期:2014-04-17 11:01:53辰龙
日期:2014-04-15 12:45:46亥猪
日期:2014-04-11 09:06:23射手座
日期:2014-04-01 15:28:10
3 [报告]
发表于 2013-07-09 16:15 |只看该作者
本帖最后由 zhaopingzi 于 2013-07-09 16:20 编辑

  1. awk -F";" -vOFS=";" -vii=333 '{$(NF-1)=ii++}1'  file
  2. 111;222;333;
  3. 111;222;334;
  4. 111;222;335;
  5. 111;222;336;
  6. 111;222;337;
  7. 111;222;338;
  8. 111;222;339;
复制代码

论坛徽章:
0
4 [报告]
发表于 2013-07-09 17:17 |只看该作者
多谢两位的帮助,菜鸟的我还要用shell来实现呢。。

awk -vOFS=';' -F';' '{print $1,$2,$3+NR-1}'  file

awk -F";" -vOFS=";" -vii=333 '{$(NF-1)=ii++}1'  file

上面两个都可以,我先也改好了我的shell脚本,用了下面的:

chgline=`echo $line|awk -F';' -vOFS=';' -vtmpvar=$tmp -vfldvar=$fldnum '{$fldvar=tmpvar}1'`

其中的用了 $fldvar 作为动态的赋值对象,好像只能这么写了

有一个问题

awk -F";" -vOFS=";" -vii=333 '{$(NF-1)=ii++}1'

这个最后面的1 是表示默认打印吗? 如果是默认去掉好像不行的,到底是个什么意思(只是看到别人如此用,还没理解到底什么意思),望指教?

论坛徽章:
0
5 [报告]
发表于 2013-07-09 17:51 |只看该作者
1 = true
默认action是print

所以意思就是打印当前行

论坛徽章:
0
6 [报告]
发表于 2013-07-09 18:16 |只看该作者
但是action不是在{}里吗, 下面的

awk -F";" -vOFS=";" -vii=333 '{$(NF-1)=ii++}1'

action应该是  {$(NF-1)=ii++} 吧???

论坛徽章:
0
7 [报告]
发表于 2013-07-09 18:56 |只看该作者
action不止一个

{$(NF-1)=ii++}1 # 可以看成两段命令,第一个省略了条件只有action,第二个省略的是action只有条件

可以想象成:
每一个row执行下面两段命令:
1 {$(NF-1)=ii++}
1 {print $0}

论坛徽章:
0
8 [报告]
发表于 2013-07-09 19:16 |只看该作者
原来如此,非常感谢!!回复 7# Kotokz


   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP