我在 ch.sh 中有大量 bash 变量
$ cat ch.sh
BBG=`tput setab 0`
RBG=`tput setab 1`
GBG=`tput setab 2`
.
.
.
$ cat abc
asd
bsd
csd
.
.
.
我想从 awk 访问而不声明awk -v
每个变量。有什么方法存在吗?我试过这个
source ch.sh
awk `
#Let s[asd]="B"
ta=s[$0] "BG" #s is awk array sowehow created by other file
#colour print of line in abc
` abc
请建议一些方法。
答案1
听起来你只是在想这个错误,而你真正拥有的只是一个tag="value"
成对的文件,ch.sh
所以试试这个:
$ echo 7 |
awk '
NR==FNR {
tag = val = $0
sub(/[[:space:]]*=.*/,"",tag)
gsub(/^[^=]+=[[:space:]]*"?|"?[[:space:]]*$/,"",val)
ch[tag] = val
next
}
{
tag = "var2"
print ch[tag], $0
}
' ch.sh -
zsd 7
如果这不是您需要的全部,那么编辑您的问题以提供 bash+awk 代码的最小示例,以演示您正在尝试执行的操作。
答案2
你可以,如果你真的真的必须这样做(但请阅读艾德的评论),编写一个包装器脚本,该脚本将读取带有变量的文件并将它们添加为-v
选项:
#/bin/bash
## The first argument is the file with the variables
varFile=$1
## Remove the first argument from the $@ array
shift;
## read the file and add the variables as -v declarations
while IFS="=" read -r var value; do
varString=$varString" -v $var=${value} "
done < "$varFile"
## Run awk, with the -v declarations and whatever you
## gave on the command line.
awk $varString "$@"
如果将该脚本保存runAwk.sh
在您的文件中$PATH
并使其可执行 ( chmod a+x /home/auth/bin/runAwk.sh
),则可以运行:
runAwk.sh variables.txt 'awk command' data
例如,给定这两个文件:
$ cat variables.txt
var1=bob
var2=foo
var3=baz
$ cat data
1 2
3 4
5 6
你可以运行:
$ foo.sh variables.txt '{print var1,var2,var3,$2;}' data
bob foo baz 2
bob foo baz 4
bob foo baz 6
重要的:如果变量值中有空格或其他空格,这将会失败。例如,它不能处理这个:
var1='something with spaces'
如果您确实需要处理这些值,您应该重新考虑您的方法,而不是尝试混合语言。或者,如果您不能,请使用艾德·莫顿的巧妙伎俩并将变量读入本机awk
数组。
答案3
假设您的ch.sh
文件包含有效的 shell 变量分配,您可以将这些变量导出到环境中,然后使用ENVIRON
关联数组在 AWK 脚本中引用它们。
鉴于此内容abc
:
asd
bsd
csd
此内容为ch.sh
:
BBG=`tput setab 0`
RBG=`tput setab 1`
GBG=`tput setab 2`
A纯粹是说明性的Bash 脚本可以是:
set -a
. ./ch.sh
set +a
awk '
BEGIN {
s["abc"] = "B"
s["bsd"] = "G"
s["csd"] = "R"
}
{
ta = ENVIRON[s[$0] "BG"]
printf("%s%s%s%s", ta, $0, ENVIRON["BBG"], ORS)
}
' abc
set -a
指示 shell 将所有新创建或修改的变量标记为导出(否则它们将不可用awk
)。