我们有一个很大的 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
我想知道,
- 如果我们可以获得不同行的选项卡计数
- 将选项卡计数相加,得到总和 995
- 一旦达到总和,无论从这些行中添加哪个选项卡计数,都需要连接到一行中。
请告诉我是否可以使用 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