跳至主要内容

博文

目前显示的是 十二月, 2009的博文

sed单行脚本学习笔记

Sed单行脚本学习笔记 redraiment, 2009-12-31 回家真好   前段时间忙着找工作、项目结题、写报告……反正是总有做不完的事情,哈哈。好在暂时告一段落了,应老妈强烈要求回家休息几天。这次回家除了这身衣服,只带了一本《 sed与awk 》,我觉得这种小册子最适合茶余饭后休闲之用。如果你也有兴趣学 sed ,推荐你一起看《 sed与awk 》(可以在 谷歌图书 在线阅读英文版:D)。   花了两天时间,看完了前面 sed 的部分。要掌握一个工具就要熟悉它的规则,man 等参考手册向我们介绍这些规则,教程则演示如何使用这些规则,但要将这些规则运用自如,还需要去理解别人的代码并尝试自己解决问题。在 SourceForge 上有份经典的文档:《 SED单行脚本快速参考 》(单行脚本要求命令行长度小于65个字符),由 Eric Pement 整理, Joe Hong 翻译,通篇阅读后获益良多,故撰此文和大家分享。 精彩脚本摘录 # 在每一行后面增加一空行 sed G   在参考手册中,命令G的作用是“将换行符后的保持空间内容追加到模式空间”。就像前文提到的,看过教程后只是熟悉了规则,还不能将规则运用自如,我自己写的代码是:sed 's/$/\n/',就是因为我还不熟悉每个命令会对模式空间产生什么影响。所以看到这段参考代码时感觉眼前一亮:“原来还可以这样写!” # 显示文件中的最后10行 (模拟“tail”) sed -e :a -e '$q;N;11,$D;ba'   假设文件有 N 行(N 大于10),显示最后10行也就意味着删除前的 N-10 行。在多行模式中,命令“D”可以删除模式空间中第一行;命令“N”可以将下一行追加到模式空间中,建立多行模式。因此问题转化为:“1)将整个文件的内容放入一个模式空间中;2)删除前 N-10 行。”其中问题1)通过控制语句“b”来解决:sed ':a; N; ba';至于问题二,模式“1,$”代表文本中的所有行,因此紧跟着的命令被执行N次,同理,模式“11,$”匹配后面的 N-10 行,因此“11,$D”一个执行了 N-10 次。   其实,在 GNU sed 中,命令“$q”是可以删掉的,因为在最后一行执行命令“N”就会因出错而自动退出。   另外,在

戏说C语言变量

戏说C语言变量 redraiment, 2009-12-18 好玩的问题   今早帮老师去答疑,一位同学跑来问:“使用 printf 输出 %d、%c 时,后面传的参数都是变量的值,为什么 %s 看起来和它们不一样,要传一个地址?”我说:“小伙子很有前途,一般人不问这样的问题,哈哈!”   这个问题类似 Java 中基础类型传递值、对象传递引用,这么设计是为了提高效率。对于还没学完C语言的初学者来说,如果我给他扯一堆“底层设计”或“效率”等显然不合适,还极有可能掉进“值传递还是址传递”等文字游戏漩涡中,估计到了最后也只能在他听得晕头转向时搪塞一句“当初就是这么设计的”。为了尽快得给他满意的答复,我只要想办法让 %s “看起来”和其他标记一样就行了,于是写了如下的代码: #include <stdlib.h> #include <stdio.h> typedef char STRING[80]; int main ( void ) {     STRING s = "redraiment";     int i = 1;     printf("%s, %d\n", s, i);     return EXIT_SUCCESS; }   然后我告诉他:“因为C语言不够抽象,让你知道了太多的底层实现细节,比如你知道字符串在内存中是以字符数组的形式保存的。现在我用 typedef 定义了一个字符串类型,把这些细节屏蔽掉。通过 STRING s; 来定义一个名字是 s 的字符串类型变量,这样就和用 double d; int i; 等方式定义变量一样,你无需了解它们在内存中如何实现。此时,对于 printf 来说,%s、%d 后面跟着的 s, i 都是一回事了,它们都是变量的名字,里面保存着不同类型的数据。”很幸运,前面的话解决了他的疑惑,让我剩下不少口水:P。 指针和数组的定义是个BUG   我初学C语言时,也有过类似的困惑:指针和数组别样的定义方式让我以为它们有别于普通类型。所有普通类型、自定义的结构体类型的定义方式都是 TYPE name,数据类型后面紧跟着变量名。因此,就理论上来说,你定义一个指针 int* pi,其中表示指针类型的“*”应该从属于 int。但很遗憾,实际上它