awk知识点全回顾

本文目录:
1.awk简介和基本语法格式
2.print和printf格式化输出
3.输入行的字段分隔符和行分隔符
4.BGEIN和END
5.数组
6.流程控制语句
  6.1 条件判断语句
  6.2 while循环
  6.3 do循环
  6.4 for循环
7.更完整的awk程序格式和表达式
8.awk中的变量
9.awk中的内置函数
10.自定义函数
11.getline函数
12.向awk传递变量

1. awk简介和基本语法格式

Awk自动地搜索输入文件,并把每一个输入行切分成字段。许多工作都是自动完成的,例如读取每个输入行、字段分割、存储管理、初始化等。在AWK中不需声明变量数据类型,它内置字符串类型和数值类型。

一般来说,在CentOS上安装的awk默认是gawk。它的调用格式为:

awk [OPTIONS] -f program_file [--] filename_list
awk [OPTIONS] [--] program filename_list

program是awk程序的重中之重,称为awk的程序,它的格式为PATTERN{ACTIONS}。awk每读入一行,都会先与PATTERN做匹配比较,当找到符合条件的数据就执行对应的ACTION。

其中PATTERN或ACTIONS二者可省一。省略PATTERN时表示对所有行都执行ACTIONS,省略ACTIONS表示对符合条件的行执行默认的print动作。因为二者可省一,所以用大括号{}将ACTIONS部分包围起来,以区分PATTERN和ACTIONS。

一个简单的例子,输出/etc/passwd中用户shell为/bin/bash的用户名,其中使用"-F"选项指定冒号作为分隔符。

awk -F‘:‘ ‘$7 == "/bin/bash"{print "who use bash shell: ",$1}‘ /etc/passwd

其中位置变量$1,$2...为该行的第几个字段,"$0"表示整行。

如果要输出多个字段,则字段之间使用逗号","分隔,例如{print $1,$5}但输出时,仍默认以空格分隔各输出字段。

如果action为print $1 $5,则结果会将"$1"和"$5"拼接在一起,因为空格是awk中的拼接字符。例如变量赋值name = "abc" "bcd"等价于name="abcbcd"。其实不算是拼接符,而是因为awk会忽略任何不被引号包围的空白。

2.print和printf格式化输出

awk使用print和printf输出数据,不仅可以输出到标准输出中,还可以重定向到文件中,使用管道传递给另一个命令。

  1. print
    将 $0 打印到标准输出。等价于print $0
  2. print expression, expression, …
    打印各个 expression, expression 之间由 OFS 分开, 由 ORS 终止
  3. print expression,expression,… > filename
    文件名filename必须使用双引号包围,否则被当作变量。且文件只会被打开一次。
  4. print expression,expression,… >> filename
  5. print expression,expression,… | command
    将数据传递给系统命令。命令需要使用双引号包围。
  6. printf(format,expression,expression,…)
  7. printf(format,expression,expression,…) > filename
  8. printf(format,expression,expression,…) >> filename
  9. printf(format,expression,expression,…) | command
  10. close(filename), close( command)
    断开 print 与 filename (或 command) 之间的连接
  11. system(command)
    执行 command; 函数的返回值是 command 的退出状态

如果print或printf的参数列表中含有操作符,则需要使用括号包围,否则容易产生歧义。如:

print($1, $3) > ($3 > 100 ? "bigpop" : "smallpop")
print $1, ($2 > $3)

执行系统命令的方式,可以通过管道的方式,也可以通过system()函数。注意包围命令的引号加的位置。

awk ‘BEGIN{name="ma long shuai";print (1,2,3,4) | "echo " name}‘
awk ‘BEGIN{while (("fdisk -l" | getline) >0){print $0}}‘
awk ‘BEGIN{system("fdisk -l")}‘
awk ‘BEGIN{name="ma long shuai";system("echo " name)}‘

printf命令可以输出更格式化的数据。

printf(format, value1, value2, ... , valueN)

format是一个字符串,包含按字面输出的纯文本,还包含输出格式,格式使用格式说明符"%"描述,后面跟着几个字符,这些字符控制一个value的输出格式。第一个"%"描述value1的输出格式,第二个"%"描述value2的输出格式,依次类推。因此,"%"的数量应该和被输出的value数量一样多。

例如:

{ printf("total pay for %s is $%.2f\n", $1, $2 * $3) }
{ printf("%-8s $%6.2f\n", $1, $2 * $3) }

第一个程序包含了两个要格式化的value,分别是"$1"和"$2 * $3"。这两个value的输出格式分别被"%s"和"%.2f"描述,前者表示按字符串格式输出"$1",后者表示按小数值格式输出"$2 * $3",且小数位占2位。由于printf不自带尾随换行符,因此手动加一个换行符"\n"。

第二个程序,"%-8s"表示"$1"按字符串格式输出,但短横线"-"表示要左对齐输出,"8"表示占用8个字符宽度,不足之数在右边空格补齐。"%6.2f"表示按小数格式输出"$2 * $3",且小数位占用2位,总字符数占用6位。注意,小数点也占用一个字符宽度。因此,一个可能的输出值为"123.20"。

格式说明符"%"后可跟以下几个常见字符:

  • 格式符:

    • %d,%i:十进制整数;
    • %f:显示浮点数;
    • %s:显示字符串;
    • %u:无符号整数;
    • %%:显示%自身。
  • 修饰符:
    • N:显示宽度;N为数值,宽度不足时若为左对齐则右边空格补足,若右对齐则左边空格补足。
    • -:左对齐;
    • +:显示数值正负号。
    • 0:表示以0填充。

3.输入行的字段分隔符和行分隔符

使用"-F"选项或设置内置变量"FS"可以控制输入行的字段分隔符,默认分隔符为" "。可通过正则表达式指定分隔符,其实可以认为总是以正则方式指定分隔符。

以下是几个示例和需要注意的空格分隔符:

  1. -F " ":默认的,会压缩所有前导空白,包括制表符和空格。
  2. -F " :":当空格后跟一个冒号时作为分隔符。会压缩前导空格,但不会匹配制表符,更不会压缩制表符。
  3. -F "[ ]‘:只表示一个空格,不压缩任何空白。
  4. -F "|":指定竖线作为分隔符。
  5. -F ",[ \t]*|[ \t]+":逗号后跟0或多个空白,或者只有1或多个空白时作为分隔符。

也就是说,当空格写在最前面且不被中括号包围限制的时候,总会忽略前导空格,但不一定能匹配制表符。

使用内置变量"RS"可以控制输入行的行分隔符,默认为"\n",只有遇到行分隔符时才作为"一行"记录被读取。

将其读作行分隔符不标准,应该读为"记录分隔符"。例如设置以制表符作为记录分隔符。

RS="\t"

记录分隔符变量"RS"只识别第一个字符,若设置为"\t\t",则第二个"\t"被忽略。但是控制输出记录分隔符的内置变量OFS则可识别多字符。

可通过设置FS="\n";RS=""使得awk能处理多行记录。但此时,原本的每行数据整体变成一个字段。

4.BGEIN和END

BEGIN和END是一个特殊的PATTERN,BEGIN引导的程序是在awk读取第一个文件第一行前要执行的awk程序,END引导的程序是在awk处理完最后一个文件最后一行后要执行的awk程序。通常BEGIN用于输出一个标题,或者初始化一些格式、变量等,END则用于最后的总结性输出。

所以awk稍微完整一点的格式为:

BGEIN{ACTIONS}PATTERN{ACTIONS}END{ACTIONS}

刨去BEGIN和END引导的两个程序,中间处理输入文件的程序PATTER{ACTIONS}称为"主输入循环(main input loop)"。在进入主输入循环之前,可以不用提供输入流,但进入主输入循环后,必须提供输入流。

例如,在开始处理文件前,设置输出报表的头部,在最后输出总共输出了多少行。其中print ""表示输出一个空行。

BEGIN{print "ID NAME GENDER GENDER";print ""}{print $0}END{print "total num: " NR}

5.数组

awk的数组和shell的数组类似,都支持数值index的普通数组和字符串index的关联数组,其实数值index仍然会转换成字符串格式的index,所以awk的数组类型都是关联数组。

数组格式:array_name[index]
数值赋值:array_name[1]=value1
引用数组:array_name[1]

需要注意的是,关联数组的index必须使用双引号包围,例如array_name["ma"],如果写成array_name[ma],则表示使用变量"ma"的值作为index。若"ma"变量未定义,则这会定义一个新的数组array_name[""]

使用index in array_name的方式可以判断数组array_name中是否有index下标对应的数组元素。如果有,它会返回1,否则返回0。所以判断语句可以如下:

if ( "ma" in array_name )

其实,判断某个数组变量的值是否为空也可判断该数组元素是否存在,如下。但这有副作用,当该元素不存在时,会创建它。

if ( array_name["ma"] != "" )

for循环的一种变体:

for (i in array_name){
    do something about array_name[i]
}

可以用于变量数组,其中变量"i"是变量数组时的index,array_name是数组名。这是以遍历index的方式遍历数组。由于index的顺序随机,所以遍历时顺序也是随机的。当然,遍历数组的方式有多种,以上只是for循环遍历的一种方式。

使用delete语句可以删除数组中的元素或者删除整个数组。如下:

delete array_name["ma"]  # 删除array_name中下标为ma的元素
delete array_name        # 删除数组array_name

6.流程控制语句

在ACTION中,可以使用流程控制语句。包括但不限于:

if (expression) statements
if (expression) statements else statements
while (expression) statements
for (expression; expression; expression) statements
for (expression in array) statements
do statements while (expression)

还有几个能影响循环的动作:

break:退出循环。
continue:退出当前循环,进入下一个循环
next:读入下一行,并awk程序的顶端从头开始。这个awk程序是PATTERN{action}这部分,不包括BEGIN{action}。
exit code:直接进入END,若本就在END中,则直接退出awk。如果END中的exit没有定义code,则采用前一个exit的code。

6.1 条件判断语句

if格式:

PATTERN {
  if (test_cmd){
      cmd1
      cmd2
      ...
  }
}

if-else格式为:

PATTERN {
   if (test_cmd){
      cmd1
      cmd2
      ......
      }
   else
      cmd3
}

当if或else结构中的命令只有一个,则其内可省大括号,如果超过一个,则需要使用大括号。

若采用一行书写格式,则如下:

PATTERN {if (test_cmd){cmd1;cmd2;...}else {cmd3;cmd4...}}

还有if-else if-else格式。

PATTERN {
    if (test_cmd){cmd_list1}
    else if {cmd_list2}
    else if {cmd_list3}
    else {cmd_list}
}

还支持多目操作符。

expression ? action1 : action2

其中"?"和":"还可以继续嵌套。

6.2 while循环

结构:

PATTERN {
  cmd1
  while (test_cmd)
      cmd
}

当cmd有多个时,使用大括号包围。

PATTERN {
    cmd1
    while (test_cmd){
        cmd2
        cmd3
        ....
    }
}

一行书写格式:

PATTERN{cmd1;while (test_cmd){cmd1;cmd2}}

6.3 do循环

和while循环类似,地位和shell中的until循环一样。都是至少执行一次命令列表。

结构:

PATTERN {
    do{
        cmd1
        cmd2
    } while (test_cmd)
}

6.4 for循环

结构大致如下:

PATTERN {
    for (i=1;i<=10;++i){
    cmd1
    cmd2
    }
}

for后括号中包括:变量初始值,条件判断和计数器增长表达式。

7.更完整的awk程序格式和表达式

更完整的awk程序的语法格式有以下几种:

BEGIN{actions}
END{actions}
expr{actions}
/regexp/{actions}:可被regexp匹配的行才执行actions
expr1,expr2{actions}:表示范围,从满足expr1的行开始,到满足expr2的行结束

其中:

  • expr是表达式。

    • 比较操作符有:< <= == != >= > ~ !~
    • 算术操作符有:+ - * / % ^(取幂) **(取幂)。其中**非POSIX标准,不可移植。
    • 赋值操作符有:++ -- += -= *= /= %= ^= **=。awk支持复合赋值,例如FS = OFS = "\t"表示字段分隔符和输出字段分隔符都被赋值为制表符。
  • /regexp/为正则匹配模式,表示该行能被regexp匹配则为真。还有以下两种匹配表达式,分别表示给定的字符串能(不能)匹配就为真。
    • string ~ /regexp/
    • string !~ /regexp/
  • 还有符合模式的表达式。使用逻辑操作符"&&"、"||"和"!"连接。如$4 == "Asia" && $3 > 500! (NR > 1 && NF > 3)

awk中字符串和数值数据类型是自动转换的。如果想要得到一个字符串值,可以value ""进行转换,同理,如果想要得到一个数值,可以value + 0

另外,正则表达式可以不用包围在两个斜杠中。可以将正则表达式赋值给一个变量,然后使用该变量取匹配数据。例如:

reg="^[0-9]+$"
$2 ~ reg

甚至直接使用双引号替换斜杠也允许。但不建议使用,因为一个元字符可能需要多个反斜杠来保护,使得看上去极其晦涩。

8.awk中的变量

普通变量:给变量赋值时,如果要赋值字符串,则该字符串应该使用双引号包围,特别是包含特殊字符时。赋值数值时无所谓。 字段变量:$1,$2,$3,...,$NF,还有"$0"表示整行内容。另外,可以直接赋值一个新字段或修改字段值。但这都会影响"$0"。同理,修改"$0"也会影响各字段值。
内置变量:其实可以分为两类,一类是awk内部自动修改的变量,如行数变量NR,一类是内部不会改动的系统变量,如输入字段分隔符变量FS,完全需要手动修改,这类一般都有默认值。

  • ARGV:命令行参数数组。从0开始计数知道ARGC-1。
  • ARGC:ARGV数组元素的个数。
  • FILENAME:当前处理的文件名。
  • FNR:当前处理文件的记录号。(file record num)
  • NR:已处理的总记录数。多个文件时不重置。(record num)
  • NF:当前记录的字段总数。(field num)
  • FS:输入的字段分隔符。默认为空白。(file separate)
  • OFS:输出的字段分隔符。默认为空白。(output record separate)
  • RS:输入流的记录分隔符。默认为"\n"。该变量只取值第一个字符。(record separate)
  • ORS:输出流的记录分隔符。默认为"\n"。该变量只取值的第一个字符。(output record separate)
  • OFMT:printf输出数值转换成字符串输出时的格式。默认为"%.6g"。
  • CONVFMT:printf输出数值转换成字符串输出时的格式。会被OFMT覆盖。默认为"%.6g"。
  • RLENGTH:被match函数匹配的字符串的长度。
  • RSTART:被match函数匹配的字符串的开始位置。
  • SUBSEP:下标分隔符。默认为"\034",ASCII中034代表的是双引号‘"‘。

注意,像NR、FNR、RS等的对象是记录(record),而非行。只有当RS="\n"时,读取了一行才表示读取了一条记录。

9.awk中的内置函数

awk有两类内置函数:算术函数和字符串函数。还支持自定义函数。

算术函数:

  • cos(x):取x的余弦。
  • sin(x):取x的正弦。
  • sqrt(x):取x的平方根。
  • rand():返回一个随机数r,其中0<=r<1
  • srand(x):设置rand()的种子值为x。种子值相同时,rand()的结果相同。可print srand()输出当前种子值。
  • int(x):取x的整数部分。

因此,要生成一个范围[1,n]的随机数,使用int(n*rand() + 1),要四舍五入一个数值,使用int(x + 0.5)

随机数的种子值相同时,rand的结果总是相同。如下两次运行结果,两次结果中,前两个rand()值相同,后两个rand()值不同,因为中间使用了srand()重设种子值。

awk ‘BEGIN{print rand();print rand();srand();print rand();print rand();print srand()}‘
  0.237788
  0.291066
  0.109925
  0.983692
  1504560578
awk ‘BEGIN{print rand();print rand();srand();print rand();print rand();print srand()}‘
  0.237788
  0.291066
  0.96322
  0.670495
  1504560604

字符串函数:建议下面的所有regexp都使用"//"包围。

  • index(str1,str2):返回子串str2在字符串str1中第一次出现的位置。如果没有指定str1,则返回0。
  • length(str1):返回字符串str1的长度。如果未给定str1,则表示计算"$0"的长度。
  • substr(str1,p):返回str1中从p位置开始的后缀字符串。
  • substr(str1,p,n):返回str1中从p位置开始,长度为n的子串。
  • match(str1,regexp):如果regexp能匹配str1,则返回匹配起始位置。否则返回0。它会设置内置变量RSTART和RLENGTH的值。
  • split(str1,array,sep):使用字段分隔符sep将str1分割到数组array中,并返回数组的元素个数。如果未指定sep则采用FS的值。因此该函数用于切分字段到数组中,下标从1开始。
  • sprintf(fmt,expr):根据printf的格式fmt,返回格式化后的expr。
  • sub(regexp,rep,str2):将str2中第一个被regexp匹配的字符串替换成rep,替换成功则返回1(表示替换了1次),否则返回0。注意是贪婪匹配。
  • sub(regexp,rep):将"$0"中第一个被regexp匹配的字符串替换成rep,替换成功则返回1,否则返回0。注意是贪婪匹配。
  • gsub(regexp,rep,str2):将str2中所有被regexp匹配的内容替换成rep,并返回替换的次数。
  • gsub(regexp,rep):将"$0"中所有被regexp匹配的内容替换成rep,并返回替换的次数。
  • toupper(str):将str转换成大写字母,并返回新串。
  • tolower(str):将str转换成小写字母,并返回新串。

关于替换函数sub和gsub,可以在替换字符串rep中使用"&"符号表示反向引用,引用的是整个被匹配的部分。

awk ‘BEGIN{
    print index("banana","na")
    print length("banana")
    print match("banana","na.*")
    print toupper("banana")
    print substr("banana",3)}‘
3
6
3
BANANA
nana
awk ‘BEGIN{str1="x&x";str2="banana"
        print sub(/a.*n/,str1,str2)
        print str2}‘
1
bxananxa
awk ‘BEGIN{
    print match("banana",/a.*n/)
    print RSTART,RLENGTH}‘
2
2 4
awk ‘BEGIN{print sprintf("hello %i world %5s","123","abc")}‘
hello 123 world   abc
awk ‘BEGIN{
    name="Ma long shuai"
    split(name,myname)
    for (i in myname){
        print myname[i]}
    }‘
Ma
long
shuai

纵观上述字符串函数,没有一个函数可以将匹配成功的字符串输出出来。但借助match()和RSTART、RLENGTH可以实现。

例如,取出"Ma:long:shuai"中的"long"并输出。

awk ‘BEGIN{
    name="Ma:long:shuai"
    if (match(name,/:[^:]*:/)){
        print substr(name,RSTART+1,RLENGTH-2)}}‘
long

10.自定义函数

function name(parameter-list) {
    statements
}

函数中的变量不影响函数外的变量,但可以使用外部变量。参数列表使用逗号分隔,这些参数只在函数内部生效。

可以在awk的引号内任意位置处定义函数(即使是BEGIN之前或END之后),且函数的调用位置可以在函数的定义位置之前。但注意,函数必须不能定义在BEGIN或主输入循环或END内部,否则自定义函数的大括号会和包围action的大括号冲突而报错。即如下(1)-(4)处位置可定义定义函数,在任意位置处调用函数。

awk ‘(1)BEGIN{ACTIONS}(2)PATTERN{ACTIONS}(3)END{ACTIONS}(4)‘

在函数的statements中,可以使用return expression语句,表示函数的返回值。

例如,创建一个"向字符串指定位置处插入一个字符"的函数。

awk ‘function insert(STRING, POS, INS) {
    before_tmp = substr(STRING, 1, POS)
    after_tmp = substr(STRING, POS + 1)
    return before_tmp INS after_tmp
}
BEGIN{print insert("banana",3,"x")}‘

11.getline函数

getline函数用于从文件、标准输入或管道中读取数据,并按情况设置变量的值。getline可以自动不断的加载下一行。如果能读取记录,则getline的返回值为1,遇到输入流的尾部时,返回值为0,不能读取记录(如文件没有读取权限、文件不存在)时,返回值为“-1"。

其中:

  • getline:会从主输入文件中读取记录。会同时设置$0,NF,NR,FNR。
  • getline var:会从主输入文件中读取记录,并将读取的记录赋值给变量var。会同时设置var,NR,FNR。
  • getline <file:从外部文件file中读取记录。同时会设置$0,NF。
  • getline var <file:从外部文件file中读取记录,并将读取的记录赋值给变量var。会同时设置var。
  • cmd | getline:从管道中读取记录。会同时设置$0,NF。
  • cmd | getline var:从管道中读取记录,并将读取的记录赋值给变量var。会同时设置var。

也就是说:

  1. 当getline从非主输入文件读取记录时,不会设置NR和FNR;
  2. 当getline后没有给定变量var时,会将读取的记录赋值给$0,于是会同时设置NF并切分成字段;否则将读取的记录赋值给变量var,不会设置NF切分字段。

仍然注意,从外部文件file中读取记录时,需要使用双引号包围文件名,否则被当成awk中的变量。

例如,执行Linux下的who命令并传递给getline读取,每读取一行记录,变量n自增1。

while ("who" | getline)
n++

将Linux命令date的结果保存到awk的变量date中。

"date" | getline date

当写成循环时,如:

while (getline <"file"){
    cmd...
}

这是不安全的,因为当无法读取file时,返回值为"-1",而while循环的判断条件是0和非0,所以"-1"也会进入死循环。所以,安全的写法为:

while (getline <"file" >0){
    cmd...
}

12.向awk传递变量

awk很重要且必备的能力是接受外界的变量,例如shell中的变量,shell中命令执行的结果,或者是在开始执行awk前应该初始化的变量。

例如,在shell中定义一个变量name,传递给awk使用。

awk -v awk_name="$name" ‘BEGIN{print awk_name}‘
Ma longshuai

有三种方式可以向awk传递变量:

1.将待传递变量当作文件名被awk解析。awk识别后发现是赋值语句,就认为其是变量传递。变量赋值语句必须定义awk program之后。此法定义的变量不可在BEGIN中使用,因为它是被当成文件解析的,只有在需要读取主输入文件的时候才会被解析。

awk ‘BEGIN{}PATTERN{print var1,var2,var3}‘ var1=value1 var2=value2 file1 var3=value3 var1=value4 file2

在上面的语句中,当awk执行完BEGIN程序后,准备读取主输入,于是开始解析program后的输入文件。解析时发现,var1和var2都是赋值语句,于是当成变量处理,当读取到file1时,发现只有一个参数,则当作输入文件,于是开始处理该文件。在处理file1时,var1和var2都是有效的,但var3还未赋值,因此var3无效。当处理完file1后,继续解析下一个主输入文件,此时var3被赋值,并开始处理file2。在处理file2时,var1、var2和var3都是有效的,但var1被新值覆盖。

此外,还可以将shell命令的结果赋值给这些预定义变量。如下展示了几种变量定义的方式:

name="Ma longshuai"
awk ‘program‘ OFS=":" var1="$name" var2="`echo Ma longshuai2`" var3="Ma longshuai3" var4=Malongshuai4 filename

不仅可以定义普通变量,还可以定义内置变量(如上OFS)。注意加引号的方式:为了安全,应该对所有赋值语句的value部分加上双引号,除非所赋的值不包含特殊字符。所以,如果上面的var1赋值语句写成var1=$name,将被awk解析成var1=Ma longshuai,于是var1的值为Ma,主输入文件为longshuai。

2.使用"-v"选项传递。变量赋值语句必须定义在awk program之前。这种方法定义的变量可以在BEGIN程序中使用。

除了定义在program之前,定义方式同上。每定义一个变量,都需要使用一个"-v"选项。如:

name="Ma longshuai"
awk -v OFS=":" -v var1="$name" -v var2="`echo Ma longshuai2`" -v var3="Ma longshuai3" ‘program‘ filename

3.通过参数数组ARGV的方式。

ARGV是内置的数组变量。awk内部会将命令行切分,并按规则将各参数存放到ARGV数组中,数组下标从0开始,这是awk中唯一下标从0开始的数组。在存放到ARGV时,所有的选项和program会被忽略。

每存储一个数组变量,特殊变量ARGC的值增加1。因此ARGC的值代表的是参数的个数。所以,数组变量从ARGV[0]到ARGV[ARGC-1]。

可使用类似下面的循环来遍历ARGV数组。

awk -F "\t" -v var1="value1" ‘BEGIN{
        for(i=0;i<ARGC;++i){
            print "ARGV[" i "]: " ARGV[i]
        }
        print "ARGC: " ARGC
    }‘ "a" "b" "v=1" file
  ARGV[0]: awk
  ARGV[1]: a
  ARGV[2]: b
  ARGV[3]: v=1
  ARGV[4]: file
  ARGC: 5

注意,ARGV[0]存储的是awk命令,"-F"和"-v"选项都没有存储到ARGV中。

ARGC和ARGV数组变量的值都可以手动修改。命令行分割存储完成之后,开始处理BEGIN,再处理主循环输入。因此,在BEGIN中修改ARGV中输入文件对应的值,可以改变awk所读取的输入文件,若将其设置为空,则该数组变量直接被跳过,也就不再读取该输入文件。

需要注意的是,当增加ARGV元素时,必须同时递增ARGC的值,因为awk是根据AGRC来读取ARGV的。同理,只增加ARGC的值,将导致新建ARGV数组元素,且这些新元素的值为空。也因此,如果减小ARGC的值,将导致无法访问超出ARGC-1边界的ARGV元素。

回到系列文章大纲:http://www.cnblogs.com/f-ck-need-u/p/7048359.html

转载请注明出处:http://www.cnblogs.com/f-ck-need-u/p/7509812.html

注:若您觉得这篇文章还不错请点击下右下角的推荐,有了您的支持才能激发作者更大的写作热情,非常感谢!

html { font-family: sans-serif }
body { margin: 0 }
article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary { display: block }
audio,canvas,progress,video { display: inline-block; vertical-align: baseline }
audio:not([controls]) { display: none; height: 0 }
[hidden],template { display: none }
a { background: transparent }
a:active,a:hover { outline: 0 }
abbr[title] { border-bottom: 1px dotted }
b,strong { font-weight: bold }
dfn { font-style: italic }
h1 { font-size: 2em; margin: 0.67em 0 }
mark { background: #ff0; color: #000 }
small { font-size: 80% }
sub,sup { font-size: 75%; line-height: 0; position: relative; vertical-align: baseline }
sup { top: -0.5em }
sub { bottom: -0.25em }
img { border: 0 }
svg:not(:root) { overflow: hidden }
figure { margin: 1em 40px }
hr { height: 0 }
pre { overflow: auto }
code,kbd,pre,samp { font-family: monospace, monospace; font-size: 1em }
button,input,optgroup,select,textarea { color: inherit; font: inherit; margin: 0 }
button { overflow: visible }
button,select { text-transform: none }
button,html input[type="button"],input[type="reset"],input[type="submit"] { cursor: pointer }
button[disabled],html input[disabled] { cursor: default }
button::-moz-focus-inner,
input::-moz-focus-inner { border: 0; padding: 0 }
input { line-height: normal }
input[type="checkbox"],input[type="radio"] { padding: 0 }
input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button { height: auto }
input[type="search"] { }
input[type="search"]::-webkit-search-cancel-button,
input[type="search"]::-webkit-search-decoration { }
fieldset { border: 1px solid #c0c0c0; margin: 0 2px; padding: 0.35em 0.625em 0.75em }
legend { border: 0; padding: 0 }
textarea { overflow: auto }
optgroup { font-weight: bold }
table { border-collapse: collapse; border-spacing: 0 }
td,th { padding: 0 }
* { }
*::before,*::after { }
html { font-size: 62.5% }
body { font-family: "Helvetica Neue", Helvetica, Arial, "Microsoft Yahei", sans-serif; font-size: 14px; line-height: 1.42857143; color: #333333 }
input,button,select,textarea { font-family: inherit; font-size: inherit; line-height: inherit }
a { color: #428bca; text-decoration: none }
a:hover,a:focus { color: #2a6496; text-decoration: underline }
a:focus { outline: 5px auto -webkit-focus-ring-color }
figure { margin: 0 }
img { vertical-align: middle }
.hljs { display: block; padding: 0.5em; color: #333; background: #f8f8f8 }
.hljs-comment,.hljs-template_comment,.diff .hljs-header,.hljs-javadoc { color: #998; font-style: italic }
.hljs-keyword,.css .rule .hljs-keyword,.hljs-winutils,.javascript .hljs-title,.nginx .hljs-title,.hljs-subst,.hljs-request,.hljs-status { color: #333; font-weight: bold }
.hljs-number,.hljs-hexcolor,.ruby .hljs-constant { color: #099 }
.hljs-string,.hljs-tag .hljs-value,.hljs-phpdoc,.tex .hljs-formula { color: #d14 }
.hljs-title,.hljs-id,.coffeescript .hljs-params,.scss .hljs-preprocessor { color: #900; font-weight: bold }
.javascript .hljs-title,.lisp .hljs-title,.clojure .hljs-title,.hljs-subst { font-weight: normal }
.hljs-class .hljs-title,.haskell .hljs-type,.vhdl .hljs-literal,.tex .hljs-command { color: #458; font-weight: bold }
.hljs-tag,.hljs-tag .hljs-title,.hljs-rules .hljs-property,.django .hljs-tag .hljs-keyword { color: #000080; font-weight: normal }
.hljs-attribute,.hljs-variable,.lisp .hljs-body { color: #008080 }
.hljs-regexp { color: #009926 }
.hljs-symbol,.ruby .hljs-symbol .hljs-string,.lisp .hljs-keyword,.tex .hljs-special,.hljs-prompt { color: #990073 }
.hljs-built_in,.lisp .hljs-title,.clojure .hljs-built_in { color: #0086b3 }
.hljs-preprocessor,.hljs-pragma,.hljs-pi,.hljs-doctype,.hljs-shebang,.hljs-cdata { color: #999; font-weight: bold }
.hljs-deletion { background: #fdd }
.hljs-addition { background: #dfd }
.diff .hljs-change { background: #0086b3 }
.hljs-chunk { color: #aaa }
#container { padding: 15px }
pre { border: 1px solid #ccc; display: block }
pre code { white-space: pre-wrap }
.hljs,code { font-family: Monaco, Menlo, Consolas, "Courier New", monospace }
:not(pre)>code { padding: 2px 4px; font-size: 90%; color: #c7254e; background-color: #f9f2f4; white-space: nowrap }

时间: 2024-10-05 06:10:33

awk知识点全回顾的相关文章

勒索蠕虫-WanaCrypt0r(比特币病毒)防治攻略和事件全回顾

1 事件背景 ====== 2017年5月12日星期五,全球近100个国家(中国.西班牙.意大利.葡萄牙.俄罗斯.乌克兰)的,多个行业机构的电脑感染名为WannaCry0r的勒索软件.目前据报道英国医疗.德国火车站.中国各大学教育网及内网.中国公共行业自助设备等均已经感染WannaCry0r的勒索软件.WannaCry0r勒索软件支持28种不同的语言,加密179种不同类型的文件,并要求受害者使用比特币汇款(300美金- 600美金),以解密被加密等数据文件. 点击查看最新的攻击地图 攻击地图查看

优维DevOps系列沙龙全回顾:DevOps+SRE落地实践+DevOps最后一棒

5月6日,优维科技和数人云联合主办的DevOps&SRE系列活动<DevOps&SRE 超越传统运维之道>在深圳顺利举行. 优维科技CEO王津银.数人云CEO王璞.腾讯SNG运维负责人梁定安分别分享了<DevOps与传统的融合落地实践及案例分享><SRE在传统企业中的落地实践><DevOps最后一棒,有效构建海量运营的持续反馈能力>,为大家带来了一场异彩纷呈的技术盛宴. △场面爆满 除了DevOps.SRE相关的经验,还有具体落地的案例分享,

awk知识点总结

awk命令:     Linux文本处理三剑客之一,另外还有grep,sed     ls -l `which awk`:查看awk路径     GNU awk = gawk     基本用法:         gawk [options] 'program' file file ...             program: PATTERN {ACTION STATEMENT}                 由语句组成,语句分隔符是;             ACTION: print,

iOS知识点全梳理-备用

感谢大神分享 文/Jack_lin(简书作者)原文链接:http://www.jianshu.com/p/5d2163640e26著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”. 序言 目前形势,参加到iOS队伍的人是越来越多,甚至已经到供过于求了.今年,找过工作人可能会更深刻地体会到今年的就业形势不容乐观,加之,培训机构一火车地向用人单位输送iOS开发人员,打破了生态圈的动态平衡.矫情一下,言归正传,我奉献一下,为iOS应聘者梳理一下面试题,希望能助一臂之力! OC的理解与特性

awk知识点

awk中删除重复行(转) 1.去除部分字段重复的行 sort+uniq也可以完成,但是awk真的很强大.两者的差异还在于,awk保持了文件中原本的每行的顺序,而sort必须排序,这样就变成按字母或某种其他规则的排序了. less num.list |awk '$1~/84[0-9]/'|awk '!a[$1]++' 2.去除记录重复的行 awk去除重复行,思路是以每一行的$0为key,创建一个hash数组,后续碰到的行,如果数组里已经有了,就不再print了,否则将其print 在awk中,可以

js面试题知识点全解(一作用域和闭包)

问题: 1.说一下对变量提升的理解 2.说明this几种不同的使用场景 3.如何理解作用域 4.实际开发中闭包的应用 知识点: js没有块级作用域只有函数和全局作用域,如下代码: if(true){ var name='killua' //把name定义在块里和放在外面是一样的,等同于在外面声明一个变量name,在块内给name赋值 }//同等于下面的代码 //建议用下面方式写 var name if(true){ name='killua' } console.log(name) //打印出来

js面试题知识点全解(一原型和原型链1)

1.如何准确判断一个变量是数组类型2.写一个原型链继承的例子3.描述new一个对象的过程4.zepto(或其他框架)源码中如何使用原型链知识点:1.构造函数2.构造函数-扩展3.原型规则和示例4.原型链5.instanceof 讲解: 构造函数:一般函数为大写字母开头的都是构造函数,如下: function Foo(name,age){ this.name=name this.age=age //return this }var f = new Foo('L',20) ; //构造函数形成实例,

关于最近一些问题和知识点的回顾的随笔

1.看代码时发现了JQuery的end()方法:该方法能够结束JQuery命令链中当前的筛选操作,并将匹配元素集还原为原本的状态.JQuery文档中是这么定义的:JQuery回到最近的一个“破坏性”对象之前,即将匹配的元素列表还原为前一次的状态. 比如,$("p").find("span").end().css("border", "2px red solid"); 这里就是先找到p下的span元素,然后调用end(),再返回

OpenSSL心脏出血漏洞全回顾

近日网络安全界谈论的影响安全最大的问题就是Heartbleed漏洞,该漏洞是4月7号国外黑客曝光的.据Vox网站介绍,来自Codenomicon和谷歌安全部门的研究人员,发现OpenSSL的源代码中存在一个漏洞,可以让攻击者获得服务器上64K内存中的数据内容.该漏洞在国内被译为” OpenSSL心脏出血漏洞”,因其破坏性之大和影响的范围之广,堪称网络安全里程碑事件. OpenSSL心脏出血漏洞的大概原理是OpenSSL在2年前引入了心跳(heartbeat)机制来维持TLS链接的长期存在,心跳机