我是一个使用awk/grep等工具的新手,我想过滤一些数据。我有一个很大的电子表格,我想要一列一列地显示唯一值。例如,我想要更改以下内容:
DS571187 DS571220 DS571200 DS571194
contig1 contig3 contig4 contig7
contig2 contig3 contig4 contig7
contig1 contig4 contig6 contig8
contig1 contig5 contig6 contig9
contig2 contig4 contig6 contig9
contig2
contig2 类似下面这样的东西:
DS571187 DS571220 DS571200 DS571194
contig1 contig3 contig4 contig7
contig2 contig4 contig6 contig8
contig5 contig9 基本上,我尝试将每一列作为其自己的列表进行排序,并以这种方式获得唯一值。任何帮助都将不胜感激。
琥珀色
发布于 2016-08-22 22:48:42
假设您的输入文件是以制表符分隔的,如下所示:
$ cat tst.awk
BEGIN { FS=OFS="\t" }
{
for (colNr=1;colNr<=NF;colNr++) {
if (!seen[colNr,$colNr]++) {
val[++colRowNr[colNr],colNr] = $colNr
numRows = (colRowNr[colNr] > numRows ? colRowNr[colNr] : numRows)
}
}
numCols = (NF > numCols ? NF : numCols)
}
END {
for (rowNr=1;rowNr<=numRows;rowNr++) {
for (colNr=1;colNr<=numCols;colNr++) {
printf "%s%s", val[rowNr,colNr], (colNr<numCols ? OFS : ORS)
}
}
}
$ awk -f tst.awk file | column -s$'\t' -t
DS571187 DS571220 DS571200 DS571194
contig1 contig3 contig4 contig7
contig2 contig4 contig6 contig8
contig5 contig9对column的调用只是为了让对齐在站点上看起来更漂亮。
如果它不是制表符分隔的,那么为了简洁和可靠地实现这一点,你需要GNU awk for FIELDWIDTHS来识别中行中可能的空字段,比如这个输入(你应该测试其他可能的解决方案,因为我预计在你的实际数据中,后来的输入列可能比之前的列更短,这会使这个问题更难解决):
$ column -s$'\t' -t file
DS571187 DS571220 DS571200 DS571194
contig1 contig3 contig4 contig7
contig2 contig3 contig7
contig1 contig4 contig8
contig5 contig9
contig9
$ awk -f tst.awk file | column -s$'\t' -t
DS571187 DS571220 DS571200 DS571194
contig1 contig3 contig4 contig7
contig2 contig4 contig8
contig5 contig9发布于 2016-08-22 23:30:36
可能需要Gawk,制表符应该是分隔符,任何一个字符分隔符都可以使用(下面的-F"\t"):
$ cat > cs.awk
NR==1 {
nf=NF
$1=$1
print
}
NR>1 {
for(i=1;i<=NF;i++)
if($i!="")
a[i][$i]++
}
END {
for(i=1;i<=nf;i++)
n[i]=asorti(a[i])
j=asort(n)
for(i=1;i<=n[j];i++)
for(k=1;k<=nf;k++)
printf "%-8s%s", a[k][i], (k<nf?OFS:ORS)
}
$ awk -F"\t" -f cs.awk cs_by_ed.txt
DS571187 DS571220 DS571200 DS571194
contig1 contig3 contig4 contig7
contig2 contig4 contig8
contig5 contig9发布于 2016-08-23 01:22:40
一种不同的方法,不一定有效,但更容易理解。最后两行用于漂亮的打印。
$ function f() { cut -d$'\t' -f$1 file1 | sed '/^$/d' | sort -u; };
paste -d$'\t' <(f 1) <(f 2) <(f 3) <(f 4) |
sed 's/\t/ \t/g' |
column -ts$'\t'
DS571187 DS571220 DS571200 DS571194
contig1 contig3 contig4 contig7
contig2 contig4 contig6 contig8
contig5 contig9https://stackoverflow.com/questions/39082214
复制相似问题