使用 sed / awk / bash 将缺失的行号填充到文件中

Posted

技术标签:

【中文标题】使用 sed / awk / bash 将缺失的行号填充到文件中【英文标题】:Fill missing line numbers into file using sed / awk / bash 【发布时间】:2021-07-08 23:57:57 【问题描述】:

我有一个(制表符分隔的)文件,其中每行的第一个“单词”是行号。但是,缺少一些行号。我想插入新行(带有相应的行号),以便在整个文件中,行上打印的数字与实际行号匹配。 (这是为了以后在 readarray 中使用 cut/awk 来获取行号之后的行。)

我已经在 python 中编写了这个逻辑并测试了它的工作原理,但是我需要在没有 python 的环境中运行它。实际文件大约有 10M 行。有没有办法使用 sed、awk 甚至只是普通的 shell / bash 来表示这个逻辑?

linenumre = re.compile(r"^\d+")
i = 0
for line in sys.stdin:
    i = i + 1
    linenum = int(linenumre.findall(line)[0])

    while (i < linenum):
        print(i)
        i = i + 1

    print(line, end='')

测试文件如下:

1   foo 1
2   bar 1
4   qux 1
6   quux    1
9       2
10  fun 2

预期输出如下:

1   foo 1
2   bar 1
3
4   qux 1
5
6   quux    1
7
8
9       2
10  fun 2

【问题讨论】:

1000 万行不是 shell 的工作,不是它做不到,而是需要永远完成 :-) 【参考方案1】:

这样,awk:

awk 'while(++ln!=$1)print ln1' input.txt

解释,作为多行脚本:



    # Loop as long as the variable ln (line number)
    # is not equal to the first column and insert blank
    # lines.

    # Note: awk will auto-initialize an integer variable
    # with 0 upon its first usage

    while(++ln!=$1) 
        print ln
    


1 # this always expands to true, making awk print the input lines

【讨论】:

太棒了,感谢您解释语法!我不知道使用 1 来打印输入行【参考方案2】:

我已经在 python 中编写了这个逻辑并测试了它的工作原理,但是我需要在没有 python 的环境中运行它。

如果您想在未安装 python 的情况下运行 python 代码,您可以冻结您的代码。 The Hitchhiker's Guide to Python 概述了能够做到这一点的工具。我建议先尝试pyinstaller,因为它支持各种操作系统,而且看起来很容易使用。

【讨论】:

【参考方案3】:

这可能对你有用(GNU join、seq 和 join):

join -a1 -t' ' <(seq $(sed -n '$s/ .*//p' file)) file 2>/dev/null

使用file 中的最后一个行号与file 加入由命令seq 创建的文件。

【讨论】:

以上是关于使用 sed / awk / bash 将缺失的行号填充到文件中的主要内容,如果未能解决你的问题,请参考以下文章

awk用法

使用 BASH 或 awk 或 sed 或其他方式删除文件的前两行

如何使用 vim 命令或 sed/awk 命令将具有不同列数的行分隔到另一个文件中? [关闭]

使用 awk/sed/bash 检索所有必填字段后打印

在 bash/sed/awk 中提取文件的最后一个单词

sed与awk