Bash 删除第一列中的重复记录,但不要修改其余列

Bash 删除第一列中的重复记录,但不要修改其余列,bash,awk,Bash,Awk,我想删除第1列中的重复记录,保留第一个实例。但保持其他栏目不受影响 输入 输出 444444 21-84,87,85-86,88-106,108,111,109,112,110,113,115,114,117, 116,118,124-125,120,122-123,126,132. 25-84,87,85-86,88-106,108,111,

我想删除第1列中的重复记录,保留第一个实例。但保持其他栏目不受影响

输入

输出

444444              21-84,87,85-86,88-106,108,111,109,112,110,113,115,114,117, 
                    116,118,124-125,120,122-123,126,132.                       
                    25-84,87,85-86,88-106,108,111,109,112,110,113,115,114,117, 
                    110,118,124-125,120,122-123,126,132.                       
111111              21-84,87,85-86,88-106,108,111,109,112,110,113,115,114,117, 
                    116,118,124-125,120,122.                                   
                    21-84,87,85-86,88-106,108,111,109,112,110,113,115,114,117, 
232323              20-84,87,85-86,88-106,108,111,109,112,110,113,115,114,117, 
                    116,118,124-125,120,122-123,126,132.                      
我试过了

 awk '!NF {print;next}; !($1 in a) {a[$1];print}' file
此外,还尝试将文件拆分为两部分:

file 1: first column and remove the duplicates and keep first > output1
file 2: Second Column 
paste output1 file2 > file-output.

是否有在简单awk行中执行的选项。

如果您的输入文件按第一列排序,如您所示,则以下内容可能会对您有所帮助

awk 'prev==$1{$1="                   "} 1; {prev=$1}'   Input_file
 awk '++a[$1]>1{$1="                   "} 1'   Input_file
解决方案2:如果您的输入文件未排序,则以下内容可能会对您有所帮助

awk 'prev==$1{$1="                   "} 1; {prev=$1}'   Input_file
 awk '++a[$1]>1{$1="                   "} 1'   Input_file

awk
可能适用于您:

awk 'seen[$1]++{$1="\t\t"} 1' file


保持行的格式

你可以试试

awk '$1!=prev{prev=new=$1;gsub("."," ",new);print;next}{sub($1,new)}1' input
如果$1包含regexp元字符

awk '
  $1!=prev {
    prev=new=$1
    gsub("."," ",new)
    print
    next }
  { i=split($1,a,//)
    b=""
    for(j=1;j<=i;j++)
    b=b "[" a[j] "]"
    sub(b,new) }
1' input
awk'
$1!=上{
上一次=新=1美元
gsub(“.”,新)
打印
下一个}
{i=split($1,a,/)
b=“”

对于(j=1;j任何修改$1的操作都会修改记录。真正做到你要求的方法是:

$ awk 'seen[$1]++{rep=$1; gsub(/./," ",rep); sub(/[^[:space:]]+/,rep)} 1' file
444444              21-84,87,85-86,88-106,108,111,109,112,110,113,115,114,117,
                    116,118,124-125,120,122-123,126,132.
                    25-84,87,85-86,88-106,108,111,109,112,110,113,115,114,117,
                    110,118,124-125,120,122-123,126,132.
111111              21-84,87,85-86,88-106,108,111,109,112,110,113,115,114,117,
                    116,118,124-125,120,122.
                    21-84,87,85-86,88-106,108,111,109,112,110,113,115,114,117,
232323              20-84,87,85-86,88-106,108,111,109,112,110,113,115,114,117,
                    116,118,124-125,120,122-123,126,132.

上面的删除重复的$1值,并保留所有其他内容,包括字段内和字段之间的空白,一如原样。

anubhava,太好了,它是这样工作的,以便在2列awk'中保持相同的格式,[$1]+{$1=”“}1'文件。是的,那也可以。我添加了
\t\t
以在第一列中获得一些额外的间距。很好,第二个选项效果更好。在我的情况下,tksEd,只有当第2列中的重复行不超过2倍时才有效,如果大于2,则代码不起作用。我用更好的示例修改了输入文件.如果最后还有另一个系列的444444,那么$2将与232323一起打印。对,但是因为OP接受了基于使用SEED[]的答案数组,这必须足以解决此问题,并且他的数据必须与他发布的示例一样,以后不会重复相同的键值。@EdMorton给出一个失败$1的示例,这样我就可以看到我可以做什么。请使用$1
*
@EdMorton进行尝试,我将更新答案。*,您还有其他问题吗?任何awk都可以用于字段拆分给定一个空字符串,因为POSIX未定义要拆分的regexp,所以YMMV使用
split($i,a,//)
-有些AWK会做你想做的,有些肯定不会。将每个字符封装在
[]中的方法
在字符为
^
时失败,但由于
^
在置于括号表达式前面时成为否定字符,因此必须使用特殊情况,使其成为
\^
,而每隔一个字符X变成
[X]
。从所有的问题可以看出,这只是一种错误的方法-将
sub($1,new)
改为
sub(/[^[:space:]+/,new)