Unix 脚本将不同行的数据连接到一行中

Unix 脚本将不同行的数据连接到一行中

我们有一个很大的 tsv 文件,其中单行的数据被分成带有新行分隔符的不同行。

我们需要根据选项卡计数将它们连接在一起。

例如:如果假设单行的总选项卡数为 995 ,则数据将按如下方式分割:

Row Number  Tab Count
Row 1       660
Row 2       0
Row 3       300         
Row 5       20
Row 6       15
Total       995

注意:上面的行分割不一致并且有所不同。

我想添加选项卡计数,一旦总数达到 995,就需要将不同行的数据连接到一行中。

我们有以下命令来根据新行分隔符连接行。

paste -sd '\n' inputfile > output file

我想知道,

  1. 如果我们可以获得不同行的选项卡计数
  2. 将选项卡计数相加,得到总和 995
  3. 一旦达到总和,无论从这些行中添加哪个选项卡计数,都需要连接到一行中。

请告诉我是否可以使用 shell 脚本来实现这一点。

谢谢。!

答案1

与此类问题一样,最好首先纠正创建数据的过程,而不是在该过程中附加后处理阶段。话虽如此,这就是你可以做的。

$ cat file
1       2
3
1       2       3
1
2
3
$ awk -v w=3 -f script.awk file
1       2       3
1       2       3
1       2       3

awk脚本将从输入中收集制表符分隔的字段,直到收集到预设数量的字段。然后,它会将这些收集到的字段作为自己的行输出,然后继续从输入中读取。

输出中的字段数由 的值给出w,该值在命令行上传递,如上所示。请注意,这是数量领域,而不是制表符的数量。

BEGIN { OFS = FS = "\t" }

function output_line () {
    # a function that outputs the nf elements in the array a
    # separated by OFS (tab) and terminated by ORS (newline)

    for (j = 1; j < nf; ++j)
        printf("%s%s", a[j], OFS)

    printf("%s%s", a[nf], ORS)
}

{
    # a:  an array of fields that we want to output together
    # nf: the length of that array

    # just add each field to the a array
    for (i = 1; i <= NF; ++i) {
        a[++nf] = $i

        # if enough has been read, output the collected data
        if (nf == w) {
            output_line()
            nf = 0
        }
    }
}

END {
    # output any data remaining in a
    if (nf > 0)
        output_line()
}

这与

tr '\t' '\n' <file | paste - - -

对于我的小例子。在您的情况下,您可以将awk上面的脚本与 一起使用-v w=996,或者您可以键入带有 996 个破折号的tr+paste命令。

答案2

继续阅读行直到达到字段数会有帮助吗?来自另一篇文章:

awk -F'\t' '
        {while (NF<996) {getline X
                         $0 = $0 FS X
                        }
        }
1
' file

相关内容