4

我需要找到一种更快的方法来使用 awk 和 sed 等工具以特定方式对文件中的行进行编号。我需要以这种方式对每行的第一个字符进行编号:1,2,3,1,2,3,1,2,3 等。

例如,如果输入是这样的:

line 1
line 2
line 3
line 4
line 5
line 6
line 7

输出需要如下所示:

1line 1
2line 2
3line 3
1line 4
2line 5
3line 6
1line 7

这是我所拥有的一部分。$lines 是数据文件中的行数除以 3。因此,对于 21000 行的文件,我处理此循环 7000 次。

export i=0
while [ $i -le $lines ]
do
    export start=`expr $i \* 3 + 1`
    export end=`expr $start + 2`
    awk NR==$start,NR==$end $1 | awk '{printf("%d%s\n", NR,$0)}' >> data.out
    export i=`expr $i + 1`
done

基本上,这一次抓取 3 行,对它们进行编号,然后添加到输出文件中。它很慢......然后一些!我不知道另一种更快的方法来做到这一点......有什么想法吗?

4

9 回答 9

15

试试这个nl命令。

请参阅https://linux.die.net/man/1/nlman nl (或另一个链接,指向您在谷歌搜索“man nl”时出现的文档或在 shell 提示符下运行时出现的文本版本)。

如果省略了文件参数,nl 实用程序从命名文件或标准输入读取行,应用可配置的行编号过滤操作并将结果写入标准输出。

编辑:不,那是错误的,我很抱歉。该nl命令没有重新开始每n行编号的选项,它只有在找到模式后重新开始编号的选项。我会将这个答案设为社区 wiki 答案,因为它可能会帮助某人了解nl.

于 2008-12-08T20:12:25.030 回答
9

这很慢,因为您一遍又一遍地阅读相同的行。此外,您启动一​​个awk进程只是为了将其关闭并启动另一个进程。最好一次完成整个事情:

awk '{print ((NR-1)%3)+1 $0}' $1 > data.out

如果您希望在数字后有一个空格:

awk '{print ((NR-1)%3)+1, $0}' $1 > data.out
于 2008-12-08T20:19:40.990 回答
2

想到 Perl:

perl -pe '$_ = (($.-1)%3)+1 . $_'

应该管用。毫无疑问,有一个 awk 等价物。基本上,((line# - 1) MOD 3) + 1.

于 2008-12-08T20:09:43.757 回答
2

这可能对您有用:

 sed 's/^/1/;n;s/^/2/;n;s/^/3/' input
于 2011-11-21T23:55:00.143 回答
2

另一种方法是使用 grep 并匹配所有内容。例如,这将枚举文件:

grep -n '.*' <<< `ls -1`

输出将是:

1:file.a
2:file.b
3:file.c
于 2019-10-24T14:25:21.700 回答
1
awk '{printf "%d%s\n", ((NR-1) % 3) + 1, $0;}' "$@"
于 2008-12-08T20:19:36.263 回答
1

Python

import sys
for count, line in enumerate(sys.stdin):
    stdout.write( "%d%s" % ( 1+(count % 3), line )
于 2008-12-08T20:23:54.413 回答
1

你不需要为此离开 bash:

i=0; while read; do echo "$((i++ % 3 + 1)) $REPLY"; done < input
于 2009-01-04T14:30:36.673 回答
0

这应该可以解决问题。$_ 将打印整行。

awk '{print ((NR-1)%3+1) $_}' < input
1line 1
2line 2
3line 3
1line 4
2line 5
3line 6
1line 7

# cat input 
  line 1
  line 2
  line 3
  line 4
  line 5
  line 6
  line 7
于 2008-12-10T04:17:42.180 回答