在文件中添加行号的不同方法
你可以直接使用IDE提供的显示行号的功能来完成这一任务,当然你也可以使用其它方式完成此项任务。
情景如下:
工作中需要给以下代码添加行号:
#include <stdio.h>
int main(int argc, char *argv[])
{
printf("hello world!\n");
return 0;
}
首先将上述代码保存为hello.c源文件。
-
使用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 }
2.使用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获取更详细的信息。
3.使用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读取不到行就直接退出了。你不仅得不到输出,而且你的原文件内容也会被清空。
在行尾添加字符,你只需要调整打印待添加字符与当前行的顺序即可。
4.使用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
file=open("hello.c")
number = 1
for line in file:
print number, " ", line,
number += 1
这里仅仅给出了一个简单的示例,不太灵活。注意不同python版本中indent使用的符号问题。
6.使用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,这两个命令以正则表达式匹配为基础能够解决你很多的文字编辑工作,极大的提高你的工作效率。让你能够通过一个新的视角去分析文字编辑任务,常常只需要构造一个特定的正则表达式就可以了!
在这里并没有分析不同种方式的性能,对于这个任务来说性能并不重要,就直接跳过了。