AWK:确保输出块后只有一个空行

时间:2014-02-14 02:41:28

标签: awk

以下awk代码输出所需内容,只是它在每个数据块后输出两个空行。只需插入一个空行。 (如果没有最后一个{“print”\ n“}语句,则不会输出空行。使用该语句,有两个空行。我只需要一个空行。)

/Reco/ {for(i=0; i<=2; i++) {getline; print} {print "\n"}}

3 个答案:

答案 0 :(得分:3)

根据您在下面的评论,您实际上想要the line that matches /Reco/ and 2 subsequent lines and a blank line (to be inserted after that)这里是如何根据下面的成语“g”执行此操作:

awk '/Reco/{c=3} c&&c--{print; if(!c)print ""}' file

解释 - 请记住awk为您提供此功能:

WHILE read line from file
DO
    execute the users script (/Reco/{c=3} c&&c--{print; if(!c)print ""})
DONE

并且awk脚本的主体由以下内容组成:

<condition> { <action> }

语句,默认条件为TRUE,默认操作是打印当前记录/行。

上面发布的awk脚本执行以下操作:

/Reco/ {         # IF the pattern "Reco" is present on the current line THEN
    c=3          #     Set the count of the number of lines to print to 3
}                # ENDIF
c&&c-- {         # IF c is non-zero THEN decrement c and THEN
    print;       #     print the current line
    if(!c)       #     IF c is now zero (i.e. this is the 3rd line) THEN
        print "" #         print a blank line
                 #     ENDIF
}                # ENDIF

所以解析输入文件的整个执行是:

WHILE read line from file
DO
    /Reco/ {         # IF the pattern "Reco" is present on the current line THEN
        c=3          #     Set the count of the number of lines to print to 3
    }                # ENDIF
    c&&c-- {         # IF c is non-zero THEN decrement c and THEN
        print;       #     print the current line
        if(!c)       #     IF c is now zero (i.e. this is the 3rd line) THEN
            print "" #         print a blank line
                     #     ENDIF
    }                # ENDIF
DONE

如果脚本编写为:

,可能会更清楚一点
awk '/Reco/{c=3} c{c--; print; if(c == 0)print ""}' file

你得到了你正在寻找的答案但是这里是如何在awk中的某些模式之后真正打印N行:

c&&c--;/pattern/{c=N}

在你的情况下将是:

c&&c--;/Reco/{c=3}

如果您想添加额外换行符,则会变为:

c&&c--{print; if(!c)print ""} /Reco/{c=3}

如果您正在考虑使用getline,请务必先阅读http://awk.info/?tip/getline并了解所有注意事项,以便了解自己的所作所为。

P.S。以下习语描述了如何选择给定的记录范围 要匹配的特定模式:

a)打印某些模式的所有记录:

awk '/pattern/{f=1}f' file

b)在某种模式之后打印所有记录:

awk 'f;/pattern/{f=1}' file

c)在某种模式后打印第N条记录:

awk 'c&&!--c;/pattern/{c=N}' file

d)在某种模式之后打印除第N条记录以外的所有记录:

awk 'c&&!--c{next}/pattern/{c=N}1' file

e)在某种模式之后打印N条记录:

awk 'c&&c--;/pattern/{c=N}' file

f)在某种模式之后打印除N条记录之外的所有记录:

awk 'c&&c--{next}/pattern/{c=N}1' file

g)从某种模式打印N条记录:

awk '/pattern/{c=N}c&&c--' file

我将变量名称从“f”更改为“found”到“c”更改为“count” 适当的,因为它更能表达变量实际上是什么。

答案 1 :(得分:2)

@ Kevin的帖子提供了具体答案(使用print ""或@BMW建议的printf ORS),但这里有一些背景

awk

print

与:

相同
print $0

即打印当前输入行后跟输出记录分隔符 - 默认为\n并存储在特殊ORS变量中。

您可以将参数传递给print以打印除$0以外的内容(或除此之外),但记录分隔符总是会附加。

请注意,如果您将 ,分隔的多个参数传递给print,则它们将由输出字段分隔符分隔输出 - 其中默认为空格并存储在特殊变量OFS中。

相比之下, - 更灵活 - printf 函数采用格式字符串(如在C对应框架中)和所需的参数数量一样多在格式字符串中实例化占位符(字段)。 输出记录分隔符不会附加到结果中。

例如,printf相当于没有参数的print是:

printf "%s\n", $0  # assumes that \n is the output record separator

或者,更一般地说:

printf "%s%s", $0, ORS

请注意,正如名称所示,输出字段/记录分隔符(OFS / ORS)具有输入对应项({{ 1}} / FS) - 它们各自的默认值是相同的(单个空格/ RS - 虽然在解析输入时,多个相邻的空格被视为单个字段分隔符)。

答案 2 :(得分:0)

print已包含换行符。只需使用print ""