Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sorting 在unix中删除完全相同的重复列_Sorting_Unix_Awk - Fatal编程技术网

Sorting 在unix中删除完全相同的重复列

Sorting 在unix中删除完全相同的重复列,sorting,unix,awk,Sorting,Unix,Awk,假设我有一个文件,如下所示: number 2 6 7 10 number 6 13 name1 A B C D name1 B E name2 A B C D name2 B E name3 B A D A name3 A F name4 B A D A name4 A F number 2 6 7 10 13 name1 A B C D E name2 A B C D E name3 B A D A F name4 B A D A F 我希望删

假设我有一个文件,如下所示:

number 2 6 7 10 number 6 13  
name1 A B C D name1 B E   
name2 A B C D name2 B E  
name3 B A D A name3 A F  
name4 B A D A name4 A F  
number 2 6 7 10 13  
name1 A B C D E   
name2 A B C D E  
name3 B A D A F  
name4 B A D A F  
我希望删除完全相同的重复列,输出文件如下:

number 2 6 7 10 number 6 13  
name1 A B C D name1 B E   
name2 A B C D name2 B E  
name3 B A D A name3 A F  
name4 B A D A name4 A F  
number 2 6 7 10 13  
name1 A B C D E   
name2 A B C D E  
name3 B A D A F  
name4 B A D A F  
我对行使用sort和uniq命令,但不知道如何处理列。有人能推荐一个好方法吗?

您可以使用awk:

NR == 1 {
  for (ii = 1; ii <= NF; ii++) {
    cols[$ii] = ii
  }
  for (ii in cols) {
    printf "%s ", ii
  }
  print ""
}

NR > 1 {
  for (ii in cols) {
    printf "%s ", $cols[ii]
  }
  print ""
}

上面的内容可能会对列进行重新排序,但如果需要的话,再努力一点就可以解决这个问题。

这个Perl one行程序就可以做到这一点:

perl -an -e '@cols = grep { !$seen{$F[$_]}++ } 0..$#F unless @cols; print join " ", @F[@cols],"\n"' inputfile

-a将inputfile的每一行拆分为@F。文件的第一行用于从左到右构造列索引列表,只保留那些不可见的索引。接下来,它将打印@F的切片,其中每行只包含这些列

这里有一种使用awk的方法可以保持顺序

awk 'NR==1{for(i=1;i<=NF;i++)b[$i]++&&a[i]}{for(i in a)$i="";gsub(" +"," ")}1' file
工作原理 如果是第一条记录

for(i=1;i<=NF;i++)
如果字段i中包含的数据中出现了多个$i,则向数组a添加一个键为i的元素

下一个块将在所有记录(包括记录1)上执行

{for(i in a)$i="";
对于集合中的每个键,将相应字段设置为“无”

gsub(" +"," ")
删除多余的空格

1

始终计算为true,以便打印所有记录。

删除重复行只需一个awk命令即可完成:

这将跟踪一行出现的次数。一旦一行出现,a[此行]就等于1,因此当它再次出现时,[此行]已经为真,并且!否定条件,因此不打印该条件

在您的情况下,您希望删除重复的列。但是,创建一个函数转置来将行转换为列,反之亦然

我在回答以下问题时已经这样做了:


awk'{print$1、$2、$3、$4、$5、$7、$8}'文件>file.new?请注意丢失的6美元。祝你好运。@Sheller:你不应该把它作为一个答案吗?java答案可以接受吗?还是只能在Linux命令中使用?如果你已经知道公共列的索引,试试这个:awk'{$6=;$7=;print}'[filename]perl的新版本。$是什么意思?$是默认变量。如果您从右到左阅读该语句:除非定义了@cols,否则对于从0到@F中最后一个索引的每个值$\u,测试哈希%seen是否未设置为$F[$\u]和increment,以便在再次看到时测试失败,如果未看到,grep将$\u中的索引传递给@cols。
1
awk '!a[$0]++'
transpose () {
  awk '{for (i=1; i<=NF; i++) a[i,NR]=$i; max=(max<NF?NF:max)}
        END {for (i=1; i<=max; i++)
              {for (j=1; j<=NR; j++) 
                  printf "%s%s", a[i,j], (j<NR?OFS:ORS)
              }
        }'
}
$ cat file | transpose | awk '!a[$0]++' | transpose
number 2 6 7 10 13
name1 A B C D E
name2 A B C D E
name3 B A D A F
name4 B A D A F