在bash中比较文件中的行

时间:2019-01-28 06:47:42

标签: bash shell awk

input.txt文件

12345678,Manoj,23,Developer
12345678,Manoj,34,Developer
12345678,Manoj,67,Developer
12345679,Vijay,12,Tester
12345679,Vijay,98,Tester
12345676,Samrat,100,Manager
12345676,Samrat,25,Manager
12345676,Samrat,28,Manager

所需的输出文件

12345678,Manoj,23,Developer,0
12345678,Manoj,34,Developer,1
12345678,Manoj,67,Developer,2
12345679,Vijay,12,Tester,0
12345679,Vijay,98,Tester,1
12345676,Samrat,100,Manager,0
12345676,Samrat,25,Manager,1
12345676,Samrat,28,Manager,2

说明

这是我输入文件的前3行中的第一个值,即12345678相同,因此请分别在前3行中附加,0 ,1 and ,2。并类似于以下几行。

如何在Shell脚本中完成此操作。

在所需输出中编辑

是否也可以将所需的输出编号格式更改为以下输出格式?

12345678,Manoj,23,Developer,0000000
12345678,Manoj,34,Developer,0000001
12345678,Manoj,67,Developer,0000002
12345679,Vijay,12,Tester,0000000
12345679,Vijay,98,Tester,0000001
12345676,Samrat,100,Manager,0000000
12345676,Samrat,25,Manager,0000001
12345676,Samrat,28,Manager,0000002

新功能: 是否可以从0000019开始编号。是否还有其他选项可以初始化变量,例如a = 5,a = 19,a = 39,之后可以在其中递增。

12345678,Manoj,23,Developer,0000019
12345678,Manoj,34,Developer,0000020
12345678,Manoj,67,Developer,0000021
12345679,Vijay,12,Tester,0000019
12345679,Vijay,98,Tester,0000020
12345676,Samrat,100,Manager,0000019
12345676,Samrat,25,Manager,0000020
12345676,Samrat,28,Manager,0000021

4 个答案:

答案 0 :(得分:7)

使用awk:

$ awk 'BEGIN{FS=OFS=",";RS="\r?\n"}{print $0,a[$1]++}' file

输出:

12345678,Manoj,23,Developer,0
12345678,Manoj,34,Developer,1
12345678,Manoj,67,Developer,2
12345679,Vijay,12,Tester,0
12345679,Vijay,98,Tester,1
12345676,Samrat,100,Manager,0
12345676,Samrat,25,Manager,1
12345676,Samrat,28,Manager,2

修改

随着需求的变化和大量评论的出现,这是最终版本(修订版,因为需求在评论和操作规范中有所不同,请敲开木头):

$ awk 'BEGIN{FS=","}{sub(/\r$/,"");printf "%s,%07d" ORS,$0,a[$1]++}' file

解释:

$ awk '
BEGIN { 
    FS=","
    # ORS="\r\n"                     # uncomment if Windows line-endings are desired
}      
{
    sub(/\r$/,"")                    # remove Windows line-endings (ie. \r from \r\n)
    printf "%s,%07d" ORS,$0,a[$1]++  # output zeropadded running count on $1
}' file

使用gawk,mawk,busybox awk和原始awk(awk版本20121220)进行了测试。哦,五年前回收了我的Solaris盒。 ; D

答案 1 :(得分:2)

更新以修复我以前未知的行尾error

使用此方法,将同时在\r\n\n行尾使用,输出将在\n结尾:

awk -F, 'sub(/\r$/,"") ($(NF+1)=sprintf("%07d",a[$2]++))' OFS=, input.txt

输出:

12345678,Manoj,23,Developer,0000000
12345678,Manoj,34,Developer,0000001
12345678,Manoj,67,Developer,0000002
12345679,Vijay,12,Tester,0000000
12345679,Vijay,98,Tester,0000001
12345676,Samrat,100,Manager,0000000
12345676,Samrat,25,Manager,0000001
12345676,Samrat,28,Manager,0000002

我这样写是为了简洁,在功能上等于:

awk 'BEGIN{FS=OFS=","}{sub(/\r$/,"");$(NF+1)=sprintf("%07d",a[$2]++)}1' input.txt

如果您安装了ruby

ruby -aF, -pe 'BEGIN{a=Hash.new(-1)};sub(/\r?$/, "," + "%07d" % a[$F[1]]+=1)' input.txt

相同的输出。

顺便说一句,如果您希望它以19开头,则可以使用它(将19+添加到值中):

awk 'sub(/\r$/,"") ($(NF+1)=sprintf("%07d",19+a[$2]++))' FS=, OFS=, input.txt

或者这个(以18初始化):

ruby -aF, -pe 'BEGIN{a=Hash.new(18)};sub(/\r?$/, "," + "%07d" % a[$F[1]]+=1)' input.txt

这些都使用$2(第2列)作为键,因为在示例中$1$2是相关的,因此使用其中任何一个都可以。

答案 2 :(得分:1)

请尝试以下操作(无需编辑行,只需按附加数组的计数值打印即可)

awk 'BEGIN{FS=OFS=","} {printf("%s,%07d\n",$0,count[$2]++)}' Input_file

答案 3 :(得分:1)

使用Perl

$ cat manoj.txt
12345678,Manoj,23,Developer
12345678,Manoj,34,Developer
12345678,Manoj,67,Developer
12345679,Vijay,12,Tester
12345679,Vijay,98,Tester
12345676,Samrat,100,Manager
12345676,Samrat,25,Manager
12345676,Samrat,28,Manager
$ perl -F, -lane ' $F[$#F]=~s/\r//g; $F[$#F+1]=sprintf("%07d",$kv{$F[0]}++);$,=",";  print @F ' manoj.txt
12345678,Manoj,23,Developer,0000000
12345678,Manoj,34,Developer,0000001
12345678,Manoj,67,Developer,0000002
12345679,Vijay,12,Tester,0000000
12345679,Vijay,98,Tester,0000001
12345676,Samrat,100,Manager,0000000
12345676,Samrat,25,Manager,0000001
12345676,Samrat,28,Manager,0000002
$