我试图在 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_len
var
:
我们在子 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