awk 多行合并

时间: 2010-05-24 / 分类: 系统运维, 通用线程 / 浏览次数: 802 views / 0个评论 发表评论

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.awk
BEGIN {
    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}}' filename
ok, 这样就可以了


发表评论

您的昵称 *

您的邮箱 *

您的网站