从包含组的文件中获取每个第n行,并且在列中给出n

时间:2017-10-17 07:29:37

标签: python r bash shell awk

关于如何返回每一行,我看过herehere;但我的问题不同。文件中的单独列提供有关要返回的第n个元素的详细信息;根据小组不同而不同。以下是Nth列提供要返回的行的数据集示例。也就是说,对于Ida每隔3行,Idb每隔4行。数据相当大,有几个Id组。

Id  TagNo   Nth
a   A-A-3   3
a   A-A-1   3
a   A-A-5   3
a   A-A-2   3
a   AX-45   3
a   AX-33   3
b   B-B-5   4
b   B-B-4   4
b   B-B-3   4
b   BX-B2   4 

期望的输出:

Id  TagNo   Nth
 a  A-A-3   3
 a  A-A-2   3
 b  B-B-5   4

感谢您的帮助。

编辑:请注意,我想从first和每个第n项开始挑选; a每隔3,b为第4。对于小组a,它将是1st,4th, 7th ...对于小组b,它将是1st,5th, 9th行。原始输出有错误并且已完成编辑。真诚的道歉。

8 个答案:

答案 0 :(得分:6)

awk应该有效:

awk '!a[$1]++{print; if(NR>1) n=NR+$3} NR==n{print; n=NR+$3}' file

Id  TagNo   Nth
a   A-A-3   3
a   A-A-2   3
b   B-B-5   4

答案 1 :(得分:3)

对于awk解决方案,

$ cat awk-sc
{
  if(id==$1){
    nth--;
    if(nth==0){print; nth=$3}
  } else {
    id=$1;nth=$3;print
  }
}

$ awk -f awk-sc file
Id  TagNo   Nth
a   A-A-3   3
a   A-A-2   3
b   B-B-5   4

答案 2 :(得分:2)

Python解决方案。

from __future__ import print_function

with open('file.csv') as f:
    print(*next(f).split())    # header

    lastid = None
    lineno = 0
    for line in f:
        id_, tagno, nth = line.split()

        if lastid != id_:
            lineno = 0

        if lineno % int(nth) == 0:
            print(id_, tagno, nth)

        lastid = id_
        lineno += 1

答案 3 :(得分:2)

基础R解决方案:

do.call(rbind, lapply(split(df, df$Id), function(x) x[seq(from = 1, to = nrow(x), by = unique(x$Nth)), ]))

    Id TagNo Nth
a.1  a A-A-3   3
a.4  a A-A-2   3
b    b B-B-5   4

答案 4 :(得分:2)

这是一个application.properties解决方案 一,数据。我假设你用base R读了它。

dat <- read.csv("file.csv")

现在是dat <- structure(list(Id = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L), .Label = c("a", "b"), class = "factor"), TagNo = structure(c(3L, 1L, 4L, 2L, 6L, 5L, 9L, 8L, 7L, 10L), .Label = c("A-A-1", "A-A-2", "A-A-3", "A-A-5", "AX-33", "AX-45", "B-B-3", "B-B-4", "B-B-5", "BX-B2"), class = "factor"), Nth = c(3L, 3L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L)), .Names = c("Id", "TagNo", "Nth"), class = "data.frame", row.names = c(NA, -10L)) 代码。

R

答案 5 :(得分:2)

awk 单线

$ awk 'a!=$1{a=$1; n=$3; k=-1} FNR>1 && ++k%n!=0{next} 1' f1
Id  TagNo   Nth
a   A-A-3   3
a   A-A-2   3
b   B-B-5   4

a!=$1{a=$1; n=$3; k=-1}a是一个跟踪第一个字段/列的变量。如果a未初始化或第一列与上一列不同,那么这将满足,并将设置ank=-1

FNR>1 && ++k%n!=0{next}:在第一行/标题行后面的每一行增加k 如果n的余数不给零,则意味着它不是第n条记录而不打印它。否则它是nth并打印出来。

以下版本可帮助您更好地理解:

$ awk 'FNR==1{print; next;}  a!=$1{a=$1; n=$3; k=0; print; next} ++k%n==0{print}' f1
Id  TagNo   Nth
a   A-A-3   3
a   A-A-2   3
b   B-B-5   4

FNR==1{print; next;}:只需打印标题,不执行任何操作

a!=$1{a=$1; n=$3; k=0; print; next}a是一个跟踪第一个字段/列的变量。如果a未初始化或第一列与上一列不同,则设置ank=0

++k%n==0{print}:对每条新记录保持递增k,如果n的余数为零则表示它是第n条记录。

答案 6 :(得分:2)

使用data.table

df <- data.table(read.table(text = "Id  TagNo   Nth
a   A-A-3   3
a   A-A-1   3
a   A-A-5   3
a   A-A-2   3
a   AX-45   3
a   AX-33   3
b   B-B-5   4
b   B-B-4   4
b   B-B-3   4
b   BX-B2   4", header = T))

df <- df[, id := seq_len(.N), by = Id]
df[id %% Nth == 1 , 1:3, by = Id]

  Id TagNo Nth
1:  a A-A-3   3
2:  a A-A-2   3
3:  b B-B-5   4

答案 7 :(得分:0)

Python解决方案:

with open('YOURFILENAME', 'r') as f:
    i = 1
    print('Id  TagNo   Nth')
    for line in f.readlines():
        if not i:
            print(line, end='')
            i = int(line.split()[-1])
        i -= 1

您可以将print()更改为write()或您想要的任何其他功能。 由于标题是固定的,我没有将它包含在我的代码中。

更新:单独打印标题。