跳到主要内容

在文件中添加行号的不同方法

你可以直接使用 IDE 提供的显示行号的功能来完成这一任务,当然你也可以使用其它方式完成此项任务。

情景如下:

工作中需要给以下代码添加行号 :

    #include <stdio.h>

int main(int argc, char *argv[])
{
printf("hello world!\n");

return 0;
}

首先将上述代码保存为 hello.c 源文件。

  1. 使用 cat -n -n (number all output lines 给所有输出行编号 )执行命令 cat -n hello.c,输出结果如下:
        [longyu@debian:15:47:12] tmp $ cat -n hello.c 
1 #include <stdio.h>
2
3 int main(int argc, char *argv[])
4 {
5 printf("hello world!\n");
6
7 return 0;
8 }
  1. 使用 nl 命令

nl 命令的全称为 number lines of files

使用 nl 命令,你可以更灵活的处理这个问题,可以指定添加行号的格式等等。


[longyu@debian:15:58:47] tmp $ nl -v1 -i1 -l1 -s' ' -w1 -bt -fn hello.c
1 #include <stdio.h>

2 int main(int argc, char *argv[])
3 {
4 printf("hello world!\n");

5 return 0;
6 }

这个命令有很多有用的参数,感兴趣的读者可以查看 linux 中的 manpage 获取更详细的信息。

  1. 使用 awk 命令

awk 可能是最灵活方式,关键在于使用 printf、print 来格式化输出每一行,如果你想要在行后添加(不常用)字符的话你也能够轻松做到!

可以有以下两种方式:

a. 使用内建变量 NR

    [longyu@debian:16:04:05] tmp $ awk '{printf("%d:    %s\n", NR, $0)}' hello.c 
1: #include <stdio.h>
2:
3: int main(int argc, char *argv[])
4: {
5: printf("hello world!\n");
6:
7: return 0;
8: }

b. 不使用内建变量

    [longyu@debian:16:05:50] tmp $ awk 'BEGIN{lines = 1} {printf("%d:    %s\n", lines++, $0)}' hello.c 
1: #include <stdio.h>
2:
3: int main(int argc, char *argv[])
4: {
5: printf("hello world!\n");
6:
7: return 0;
8: }

这里 awk 直接将格式化后的每行打印到标准输出,你可以通过使用重定向,将 awk 的输出重定向到一个新的文件中。注意不能使用输入文件,如果你在上述命令之后添加了 > hello.c 重定向操作,那么 hello.c 将会由 shell 截断为 0,然后 awk 读取不到行就直接退出了。你不仅得不到输出,而且你的原文件内容也会被清空。

在行尾添加字符,你只需要调整打印待添加字符与当前行的顺序即可。

  1. 使用 sed

    其实我最先考虑的工具就是 sed。我马上就想到了 sed 中的 '=' 命令能够打印行号,只是会将行号单独打印在一行中,这也就意味着单个命令无法完成这个工作。然后我想到了可以使用多行模式空间,使用 sed 的高级语法 N 命令来将处理行与行号输出行以换行符分割读入到模式空间中,然后我再替换掉换行符就完成了这个任务。

       [longyu@debian:17:52:22] tmp $ sed '=' hello.c | sed '{N 
    s/\n/: /}'
    1: #include <stdio.h>
    2:
    3: int main(int argc, char *argv[])
    4: {
    5: printf("hello world!\n");
    6:
    7: return 0;
    8: }
5. 使用 python
```py
file=open("hello.c")
number = 1

for line in file:
print number, " ", line,
number += 1

这里仅仅给出了一个简单的示例,不太灵活。注意不同 python 版本中 indent 使用的符号问题。

  1. 使用 c 语言

    这里直接使用 linux 中 manpage 给出的示例代码来完成此项任务。 代码如下:

    #include <stdio.h>
#include <stdlib.h>

#define _GNU_SOURCE

int main(int argc, char *argv[])
{
FILE *fp;
char *line = NULL;
size_t len = 0;
ssize_t read;
int lines = 1;

if (argc != 2) {
fprintf(stderr, "Usage:%s filename\n", argv[0]);
exit(EXIT_FAILURE);
}

fp = fopen(argv[1], "r");
if (fp == NULL)
exit(EXIT_FAILURE);

while ((read = getline(&line, &len, fp)) != -1) {
printf("%d %s", lines++, line);
}

free(line);
fclose(fp);
exit(EXIT_SUCCESS);
}

核心在于使用 getline 将每一行读入到内存中,然后使用 printf 来输出添加了行号的结果,行号由一计数变量完成。

如果任务更加复杂,例如我需要在指定行的特定单词之后插入某个字符,这时 sed 与 awk 的威力就能够表现出来了。IDE 提供的普通的查找替换操作只适用于相对简单的情况,稍微复杂点的情况就需要分为多个步骤或者根本无法直接做到。这时你可以考虑使用 sed 与 awk,这两个命令以正则表达式匹配为基础能够解决很多的文字编辑工作中的问题,极大的提高你的工作效率。让你能够通过一个新的视角去分析文字编辑任务,常常只需要构造一个特定的正则表达式就可以了!

在这里并没有分析不同种方式的性能,对于这个任务来说性能并不重要,就直接跳过了。