如何获取传递给 awk 的变量计数

如何获取传递给 awk 的变量计数

我试图在 bash 脚本中调用 awk 并向其传递一些 bash 变量值。有没有办法获得这些变量的计数并打印 awk 中传递给它的所有变量。

传递给 awk 的变量数量是动态的。

下面的例子

#!/bin/bash
NAME="Dell"
SERIAL="12345"
echo "Hello" | awk -v a=$NAME -v b=$SERIAL '{ print a,b }'

参考,工作示例,Irvur 的回答在这里

#!/bin/bash

function confirm_peers (){
  header_def=("${header_def[@]:-None}")
  read -r -p "Enter nodes from header[${header_def[*]}]: " -a header
  header=("${header[@]:-${header_def[@]}}") ;
  echo -e "\nInput Recorded - ${header[@]} \n"
}

createEncConfig()
{
 /usr/bin/awk -f - <<-'EOE' ${header[*]}  FS=":" $1
  BEGIN {
    count=1
    for (i = 1; i < ARGC - 2; ++i) {
    split(ARGV[i], ar, "=");
    print ar[2]
    }
print "\nCount=" ARGC -3
        }
EOE
}
confirm_peers
# Making array content adaptable to awk input
for x in ${!header[@]} ; do header[x]="a=${header[x]}"; done
createEncConfig $1

参考 - 迄今为止最简单的,Kusalananda 的答案

#!/bin/bash

function confirm_peers (){
  header_def=("${header_def[@]:-None}")
  read -r -p "Enter nodes from header[${header_def[*]}]: " -a header
  header=("${header[@]:-${header_def[@]}}") ;
  echo -e "\nInput Recorded - ${header[@]} \n"
}

createEncConfig()
{
/usr/bin/awk -v args="${header[*]}" -f - <<-'EOE' FS=":" $1
BEGIN {
  count=split(args,ar," ")
  for ( x in ar ) {
    print ar[x]
  }
print "\n" count
}
EOE
}
confirm_peers
createEncConfig $1

输出:只需传递任何虚拟文件

$bash /tmp/a.bsh /tmp/enc1.txt

Enter nodes from header[None]: a b c d

Input Recorded - a b c d

a
b
c
d

Count=4

谢谢大家 ..

答案1

我能想到的一种选择是重新定位这些变量,以便它们出现在ARGV.ARGC将指示其中有多少个。请注意,这会使变量在BEGIN块中不可用。您还需要考虑可能作为参数传递给的任何文件名,方法awk是从中减去此类文件的数量ARGC

echo "Hello" | awk  '{ print a, b, ARGC - 1}' a=$NAME b=$SERIAL
DELL 12345 2

答案2

你的评论,似乎您有一个数组,bash您想将其传递到awk命令行上的程序中。

这是一个简单的方法:

array=("my 1st item" "my 2nd item" "the last item")

(
    IFS=:

    awk -v var="${array[*]}" '
        BEGIN {
            array_len = split(var, array, ":")
            for (i = 1; i <= array_len; ++i)
                printf("Item #%d is \"%s\"\n", i, array[i])
        }'
)

这将输出

Item #1 is "my 1st item"
Item #2 is "my 2nd item"
Item #3 is "the last item"

这将获取数组并将其转换为由:- 分隔的项目组成的单个字符串。如果数组的任何元素包含:,则选择另一个字符来分隔字符串中的项目。的扩展${array[*]}将在 的第一个字符上连接数组中的项目$IFS,这就是我们在执行扩展之前设置此变量的原因。该字符串awk作为变量传递var

在程序BEGIN的块中awk,我们创建数组并通过分割来array跟踪数组的长度。该循环只是为了表明我们成功地分割了字符串。array_lenvar:

我们在子 shell 中设置IFS并运行awk程序,以便脚本的其余部分可以使用未修改的IFS变量运行。

答案3

现在,由于awk没有提供获取自己的命令行及其选项的方法,这有点牵强,它依赖于proc文件系统等 Linux 内部结构,但只是为了好玩(YMMV):

awk -v"VAR1=sd" -va=b -vJ=onny '
BEGIN   {("tr \47\\000\\n\47 \47\t\47 </proc/$PPID/cmdline") | getline CMDLN
         n = split (CMDLN, ELM, "\t")
         for (i=1; i<=n; i++)   if (sub ("^-v", "", ELM[i]))    {split (ELM[i], T, "=")
                                                                 print "Option", T[1], "=", T[2]
                                                                 Options++
                                                                } 
        }
'
Option VAR1 = sd
Option a = b
Option J = onny

正在读取的“命令”getline将在子 shell 中执行,因此我们获取父 PID 的命令行,以及s的和tr字符。然后,CMDLN进入其元素,在每个元素中匹配(并消除)前导“-v”以查找变量定义。这些被打印出来,并且选项计数增加。试一试。<NUL><LF><TAB>split

答案4

由于您有一个 bash 数组,并且 bash 知道数组中有多少个元素,因此只需直接告诉 awk:

$ array=("my 1st item" "my 2nd item" "the last item")
$ awk -v var="${array[*]}" -v nargs=${#array[@]} '
  BEGIN {
    print nargs;
  }
'
3

相关内容