awk

getline Command

正如你已经知道, awk脚本的body块获取输入文件的每一行执行一次。您没有办法控制, AWK将自动进行。

但是使用函数getline命令,你可以控制读入行从输入文件(或其他文件)。注意,在执行函数getline之后, awk脚本适当设定了NF NR, FNR值和$ 0个内置变量。

Simple getline

$ awk -F"," '{getline; print $0;}' items.txt
102,Refrigerator,Appliance,850,2
104,Tennis Racket,Sports,190,20
105,Laser Printer,Office,475,5

当你在body块内指定getline函数时,AWK读取输入文件的下一行。 在这个例子中,在主体块中的第一语句是函数getline 。所以,尽管已经AWK读取从输入文件中的第一行,函数getline读取下一行,因为我们明确地请求来自所述输入文件中的下一行。因此,在执行“打印$ 0'后函数getline使得AWK打印二号线。

这儿是它如何工作的:

1. 在body块的开始,执行任何语句之前, AWK读取items.txt第一行并将其存储在$0里。

2. getline - 我们强制awk来读取输入文件的下一行,并将其存储在内置$0变量。

3. print $0 - 由于2号线被读入$0,打印$0,将打印二号行(而不是1号行) 。

4. body块继续以同样的方式在读取items.txt其余行并且仅打印偶数行的。

getline to a variable

你也可以取得下一行从输入文件存入一个变量(取代$0)

The following example prints only the odd numbered lines.
$ awk -F"," '{getline tmp; print $0;}' items.txt
101,HD Camcorder,Video,210,10
103,MP3 Player,Audio,270,15
105,Laser Printer,Office,475,5

这儿它又是如何工作的:

1. 在body块的开始,执行任何语句之前, AWK读取items.txt第一行并将其存储在$0里。

2. getline tmp - 我们强制awk来读取输入文件的下一行,并将其存储在tmp变量。

3. print $0 -$0个仍然包含第一行,为“函数getline TMP ”没有覆盖$0的值。因此,打印$0,将打印一号线(而不是2号线)。

4. body块继续以同样的方式items.txt的其他行,并仅打印在奇数行。

下面的例子打印两个变量$0和tmp.如下所示,$0包含奇数行 tmp包含偶数行。

$ awk -F "," '{getline tmp; print "$0->", $0; print "tmp->", tmp;}' items.txt
$0-> 101,HD Camcorder,Video,210,10
tmp-> 102,Refrigerator,Appliance,850,2
$0-> 103,MP3 Player,Audio,270,15
tmp-> 104,Tennis Racket,Sports,190,20
$0-> 105,Laser Printer,Office,475,5

getline from a different file

前面的两个例子读取是输入文件自身的行。使用函数getline你可以从不同的文件读取行,如下所示。

来回切换,两个文件之间,打印每行。

$ awk -F"," '{print $0; getline < "items-sold.txt"; print $0;}' items.txt
101,HD Camcorder,Video,210,10
101 2 10 5 8 10 12
102,Refrigerator,Appliance,850,2
102 0 1 4 3 0 2
103,MP3 Player,Audio,270,15
103 10 6 11 20 5 13
104,Tennis Racket,Sports,190,20
104 2 3 4 0 6 5
105,Laser Printer,Office,475,5
105 10 2 5 7 12 6

它是如何工作的:

1. 在body块的开始,执行任何语句之前,AWK读取items.txt第一行并将其存储在$0

2. print $0 - 打印items.txt文件第一行

3. getline < "items-sold.txt" - 读取items-sold.txt 并存在$0里。

4. print $0 - 打印items-sold.txt第一行。

5. body块用相同的方法继续处理items.txt和items-sold.txt其他行。

getline from a different file to a variable

即便是不读取两个文件进$0,你也可以使用函数"getline var”格式从不同文件读取行存入一个变量。

两个文件之间,来回切换,打印每一行(使用tmp变量)。

$ awk -F"," '{print $0; getline tmp < "items-sold.txt"; print tmp;}' items.txt
101,HD Camcorder,Video,210,10
101 2 10 5 8 10 12
102,Refrigerator,Appliance,850,2
102 0 1 4 3 0 2
103,MP3 Player,Audio,270,15
103 10 6 11 20 5 13
104,Tennis Racket,Sports,190,20
104 2 3 4 0 6 5
105,Laser Printer,Office,475,5
105 10 2 5 7 12 6

这是与先前实施案例不同之处在于,它从第二文件中读取的行存储在变量tmp中。

getline to execute external command

您还可以使用函数getline执行UNIX命令,并得到它的输出。

下面的示例获取date命令的输出并打印它。请注意,您应该关闭你刚刚执行,如下所示。日期命令的输出被存储在$ 0个变量。

使用此方法来打印时间戳报表的页眉或页脚。

$ cat getline1.awk
BEGIN {
    FS=",";
    "date" | getline
    close("date")
    print "Timestamp:" $0
}
{
    if ( $5 <= 5 )
        print "Buy More: Order", $2, "immediately!"
    else
        print "Sell More: Give discount on", $2, "immediately!"
}


$ awk -f getline1.awk  items.txt
Timestamp:Tue Sep  1 18:35:43 CST 2015
Sell More: Give discount on HD Camcorder immediately!
Buy More: Order Refrigerator immediately!
Sell More: Give discount on MP3 Player immediately!
Sell More: Give discount on Tennis Racket immediately!
Buy More: Order Laser Printer immediately!

取代输出存储在$0个变量里,你可以将其存储在任何AWK变量里(例如:timestamp)如下所示。

$ cat getline2.awk
BEGIN {
    FS=",";
    "date" | getline timestamp
    close("date")
    print "Timestamp:" timestamp
}
{
    if ( $5 <= 5 )
        print "Buy More: Order", $2, "immediately!"
    else
        print "Sell More: Give discount on", $2, "immediately!"
}


$ awk -f getline2.awk items.txt
Timestamp:Tue Sep  1 18:40:42 CST 2015
Sell More: Give discount on HD Camcorder immediately!
Buy More: Order Refrigerator immediately!
Sell More: Give discount on MP3 Player immediately!
Sell More: Give discount on Tennis Racket immediately!
Buy More: Order Laser Printer immediately!