Bash 如果第2列字段有多个值,则格式化输出
我的数据如下所示:Bash 如果第2列字段有多个值,则格式化输出,bash,awk,ruby,Bash,Awk,Ruby,我的数据如下所示: Joe:23;23;56:zz Jim:44;44:cz Rob:45;98:fc 在第2列中,如果有多个值,则需要单独打印。 应删除重复项,并且仅打印唯一值 我尝试了以下方法来删除重复项: sort -u -t : -k 2,2 file_name Output: Joe:23;23;56:zz Jim:44;44:cz Rob:45;98:fc 期望输出: Jim:44:cz Below ones need to print separately because
Joe:23;23;56:zz
Jim:44;44:cz
Rob:45;98:fc
在第2列中,如果有多个值,则需要单独打印。
应删除重复项,并且仅打印唯一值
我尝试了以下方法来删除重复项:
sort -u -t : -k 2,2 file_name
Output:
Joe:23;23;56:zz
Jim:44;44:cz
Rob:45;98:fc
期望输出:
Jim:44:cz
Below ones need to print separately because column 2 has more than one value or we can append this output to other file.txt
Joe:23;56:zz
Rob:45;98:fc
你能试试下面的吗。这将创建两个输出文件,其中一个文件的第2列中有两个值的行,另一个输出文件的第2列中有两个以外的值。输出文件名将为
out\u file\u two\u cols
和out\u file\u more\u two\u cols
,您可以根据需要进行更改
awk '
BEGIN{
FS=OFS=":"
}
{
delete a
val=""
num=split($2,array,";")
for(j=1;j<=num;j++){
if(!a[array[j]]++){
val=(val?val ";":"")array[j]
}
}
$2=val
num=split($2,array,";")
}
num==1{
print > ("out_file_two_cols")
next
}
{
print > ("out_file_more_than_two_cols")
}
' Input_file
awk'
开始{
FS=OFS=“:”
}
{
删除
val=“”
num=拆分($2,数组“;”)
对于(j=1;j(“out\u file\u two\u cols”)
下一个
}
{
打印>(“输出文件多于两列”)
}
'输入文件
说明:在这里为BEGIN部分中输入文件的所有行设置字段分隔符和输出字段分隔符:。然后在main部分中删除名为a的数组并将变量val置零,后面部分将进一步说明并由程序使用,删除它们以避免获取i的冲突r此处为以前的值
将第二个字段拆分为数组,方法是将分隔符设置为;
,并在此处获取num变量中的元素总数。现在运行for循环,从1到num值,遍历第二个字段的所有元素
如果数组a中不存在所有元素的第二个字段的当前值,则检查条件,然后将其添加到变量val中,并继续对第二个字段的所有元素执行此操作
然后将val的值赋给第二列。现在再次检查通过拆分新的第二列中有多少元素,num将告诉我们相同的结果
如果num为1,则检查条件意味着当前/编辑的第二个字段只有1个元素,然后将其打印到一个字段输出文件中,否则将其打印到其他输出文件中。这里有一个小脚本
!/usr/bin/env ruby
输入=File.new“文件名”
single=File.new“一个值”,“w”
multiple=File.new“两个值”,“w”
输入每个do |行|
字段=行。拆分“:”
值=字段[1]。拆分(“;”).uniq.sort
字段[1]=value.join“
new_line=fields.join:“
如果value.size==1
单个另一个awk
$ awk 'function join() {
s=sep="";
for(k in b) {s=s sep k; sep=";"}
return s}
BEGIN {FS=OFS=":"}
{n=split($2,a,";");
delete b;
for(i=1;i<=n;i++) b[a[i]]
$2=join()
if(length(b)==1) print;
else {multi=multi ORS $0}}
END {print "\nmultiple values:" multi}' file
Jim:44:cz
multiple values:
Joe:23;56:zz
Rob:45;98:fc
$awk'函数联接(){
s=sep=“”;
对于(k in b){s=s sep k;sep=“;”}
返回s}
开始{FS=OFS=“:”}
{n=拆分($2,a,“;”);
删除b;
对于(i=1;i源数据:
$ cat colon.dat
Joe:23;23;56:zz
Jim:44;44:cz
Rob:45;98:fc
一个awk
解决方案:
awk -F":" ' # input field separator is colon
BEGIN { OFS=FS } # output field separate or colon
{ n=split($2,arr,";") # split field 2 by semi-colon
m=n # copy our array count
delete seen # reset seen array
for ( i=1 ; i<=n ; i++ ) { # loop through array indices
if ( arr[i] in seen ) { # if entry has been seen then ...
delete arr[i] # remove from array and ....
m-- # decrement our total count
}
else {
seen[arr[i]] # otherwise add element to the seen arrray
}
}
outf="single.out" # output file for single entries
if ( m >= 2 ) {
outf="multiple.out" # output file for multiple entries
}
printf "%s%s", $1, OFS > outf # print header
sep="" # separator for first field is empty string
for ( i in arr ) { # print remaining array elements
printf "%s%s", sep, arr[i] > outf
sep=";" # set separator to semi-colon for fields 2+
}
printf "%s%s\n", OFS, $3 > outf # print trailer
}
' colon.dat
对于第二组,您所说的“单独打印”
是什么意思?您是否希望将其打印为显示的格式(在Jim
行后面有一个空行)或者你想让Joe和Rob在第2列中的值超过1的行的输出顺序重要吗?@markp fuso我的意思是说Joe和Rob的输出需要作为第二个输出打印在另一个文件中。@markp fuso我的意思是说第二组输出需要附加到一个文件中。看;我想你可以使用RavinderSingh13的awk | split
,然后循环通过生成的数组来删除DUP。谢谢,Ravinder工作正常。你能告诉我你所做的代码吗。
$ cat single.out
Jim:44:cz
$ cat multiple.out
Joe:23;56:zz
Rob:45;98:fc