awk ARGC和ARGV

预定义变量ARGV是一个数组,包含了所有的命令行参数。该数组使用从0开始的数值作为索引。

预定义变量ARGC初始时是ARGV数组的长度,即命令行参数的数量。

ARGV数组的数量和ARGC的值只有在awk刚开始运行的时候是保证相等的。

  1. $ awk -va=1 -F: '
    BEGIN{
    print ARGC;
    for(i in ARGV){
    print "ARGV[" i "]= " ARGV[i]
    }
    }' b=3 a.txt b.txt

    4
    ARGV[0]= awk
    ARGV[1]= b=3
    ARGV[2]= a.txt
    ARGV[3]= b.txt

awk读取文件是根据ARGC的值来进行的,有点类似于如下伪代码形式:

  1. while(i=1;i<ARGC;i++){
    read from ARGV[i]
    }

默认情况下,awk在读完ARGV中的一个文件时,会自动从它的下一个元素开始读取,直到读完所有文件。

直接减小ARGC的值,会导致awk不会读取尾部的一些文件。此外,增减ARGC的值,都不会影响ARGV数组,仅仅只是影响awk读取文件的数量。

  1. # 不会读取b.txt
    awk 'BEGIN{ARGC=2}{print}' a.txt b.txt

    # 读完b.txt后自动退出
    awk 'BEGIN{ARGC=5}{print}' a.txt b.txt

可以将ARGV中某个元素赋值为空字符串””,awk在选择下一个要读取的文件时,会自动忽略ARGV中的空字符串元素。

也可以delete ARGV[i]的方式来删除ARGV中的某元素。

用户手动增、删ARGV元素时,不会自动修改ARGC,而awk读取文件时是根据ARGC值来确定的。所以,在增加ARGV元素之后,要手动的去增加ARGC的值。

  1. # 不会读取b.txt文件
    $ awk 'BEGIN{ARGV[2]="b.txt"}{print}' a.txt

    # 会读取b.txt文件
    $ awk 'BEGIN{ARGV[2]="b.txt";ARGC++}{print}' a.txt

对awk ARGC和ARGV进行操刀

awk判断命令行中给定文件是否可读

awk命令行中可能会给出一些不存在或无权限或其它原因而无法被awk读取的文件名,这时可以判断并从中剔除掉不可读取的文件。

  1. 排除命令行尾部(非选项型参数)的var=val、-、和/dev/stdin这3种特殊情况
  2. 如果不可读,则从ARGV中删除该参数
  3. 剩下的都是可在main代码段正常读取的文件
  1. BEGIN{
    for(i=1;i<ARGC;i++){
    if(ARGV[i] ~ /[a-zA-Z_][a-zA-Z0-9_]*=.*/ \
    || ARGV[i]=="-" || ARGV[i]=="/dev/stdin"){
    continue
    } else if((getline var < ARGV[i]) < 0){
    delete ARGV[i]
    } else{
    close(ARGV[i])
    }
    }
    }

打赏作者

21. awk的ARGC和ARGV详解 - 图1