awk 多行合并
awk 是一种用于读取和处理结构化数据(如系统的 /etc/passwd 文件)的极佳工具,但学习起来还是有些难度的, 今天看到一个文本如下:
#vi thisme.txt
Jimmy the Weasel 100 Pleasant Drive San Francisco, CA 12345 Big Tony 200 Incognito Ave. Suburbia, WA 67890
希望用 awk 将每 3 行看作是一个独立的记录,而不是三个独立的记录, 而像处理成如下的格式:
Jimmy the Weasel, 100 Pleasant Drive, San Francisco, CA 12345 Big Tony, 200 Incognito Ave., Suburbia, WA 67890首先的思想是将每行当作一个单位, 脚本如下所示:#vi thisme.awkBEGIN { FS="\n" RS="" } { print $1 ", " $2 ", " $3 }用 awk -f thisme.awk thisme.txt 执行却只处理了前三行的数据,只能看到一行,,,,汗继续修改脚本;BEGIN { FS="\n" RS="" ORS="" } { x=1 while ( x<NF ) { print $x "\t" x++ } print $NF "\n" }解释:首先,将字段分隔符 FS 设置成 "\n",将记录分隔符 RS 设置成 "",这样 awk 可以象以前一样正确分析多行地址。然后,将输出记录分隔符 ORS 设置成 "",它将使 print 语句在每个调用结尾 不 输出新行。这意味着如果希望任何文本从新的一行开始,那么需要明确写入print "\n"。 在主代码块中,创建了一个变量 x 来存储正在处理的当前字段的编号。起初,它被设置成 1。然后,我们使用 while 循环(一种 awk 循环结构, 等同于 C 语言中的 while 循环),对于所有记录(最后一个记录除外)重复打印记录和 tab 字符。最后,打印最后一个记录和换行;此外,由于 将 ORS 设置成 "",print 将不输出换行。程序输出如下Jimmy the Weasel 100 Pleasant Drive San Francisco, CA 12345 Big Tony, 200 Incognito Ave., Suburbia, WA 67890出是出来了, 可好像跟我们想象中的不一样啊, 三行后没有自动跳行, 太郁闷了, 看来还的继续改了{if (NR%3==0) {print $0}else {printf"%s, " ,$0}}ok, 我们在用awk 执行下, 完全达到要求, 其中NR%3中的3代表着3行如果你不是用纯awk, 而是到shell脚本中调用的话,也很简单了,把上面的改下就OK了, 改动如下:linecount=3 awk -v n=${linecount} '{if (NR%n==0){print $0} else {printf"%s ",$0}}' filenameok, 这样就可以了
上一篇: nginx 的301永久转向
下一篇: PHP文件解析漏洞
