我们可以在 awk 中使用 shell 变量吗?

我们可以在 AWK 中使用像 $VAR这样的 shell 变量而不是 $1$2吗? 例如:

UL=(AKHIL:AKHIL_NEW,SWATHI:SWATHI_NEW)


NUSR=`echo ${UL[*]}|awk -F, '{print NF}'`
echo $NUSR
echo ${UL[*]}|awk -F, '{print $NUSR}'

实际上我是一个 Oracle DBA,我们收到了很多导入请求。我试着用脚本自动化它。该脚本将查找转储中的用户,并提示需要加载转储的用户。

假设转储有两个用户 AKHILSWATHI(转储中可能有用户,我希望导入更多的用户)。我想将转储导入到新用户 AKHIL_NEWSWATHI_NEW。所以要读取的输入有些像 AKHIL:AKHIL_NEW,SWATHI:SWATHI_NEW

首先,我需要找到要创建的用户数,然后我需要从我们给出的输入中获得新用户,即 AKHIL_NEW,SWATHI_NEW。这样我就可以连接到数据库并创建新用户,然后导入。我没有复制整个代码: 我只是从它接受输入用户的地方复制了代码。

UL=(AKHIL:AKHIL_NEW,SWATHI:SWATHI_NEW) ## it can be many users like     USER1:USER1_NEW,USER2_USER2_NEW,USER3:USER_NEW..


NUSR=`echo ${UL[*]}|awk -F, '{print NF}'` #finding  number of fields or users
y=1
while [ $y -le $NUSR ] ; do
USER=`echo ${UL[*]}|awk -F, -v NUSR=$y  '{print $NUSR}' |awk -F: '{print $2}'` #getting     Users to created AKHIL_NEW and SWATHI_NEW and passing to SQLPLUS
if [[ $USER = SCPO* ]]; then
TBS=SCPODATA
else
if [[ $USER = WWF* ]]; then
TBS=WWFDATA
else
if [[ $USER = STSC* ]]; then
TBS=SCPODATA
else
if [[ $USER = CSM* ]]; then
TBS=CSMDATA
else
if [[ $USER = TMM* ]]; then
TBS=TMDATA
else
if [[ $USER = IGP* ]]; then
TBS=IGPDATA
fi
fi
fi
fi
fi
fi


sqlplus -s '/ as sysdba'  <<EOF   # CREATING the USERS in the database
CREATE USER $USER IDENTIFIED BY $USER  DEFAULT TABLESPACE $TBS TEMPORARY TABLESPACE TEMP QUOTA 0K on SYSTEM QUOTA UNLIMITED ON $TBS;


GRANT
CONNECT,
CREATE TABLE,
CREATE VIEW,
CREATE SYNONYM,
CREATE SEQUENCE,
CREATE DATABASE LINK,
RESOURCE,
SELECT_CATALOG_ROLE
to $USER;
EOF
y=`expr $y + 1`
done


impdp sysem/manager DIRECTORY=DATA_PUMP DUMPFILE=imp.dp logfile=impdp.log SCHEMAS=AKHIL,SWATHI REMPA_SCHEMA=${UL[*]}

在最后一个 impdp 命令中,我需要使用变量获得转储中的原始用户,即 AKHIL、 SWATHI。

108149 次浏览

是的,你可以在 awk 里面使用 外壳变量。有很多种方法可以做到这一点,但我最喜欢的是用 -v标志定义一个变量:

$ echo | awk -v my_var=4 '{print "My var is " my_var}'
My var is 4

只需将环境变量作为参数传递给 -v标志,例如,如果你有这个变量:

$ VAR=3
$ echo $VAR
3

这样使用:

$ echo | awk -v env_var="$VAR" '{print "The value of VAR is " env_var}'
The value of VAR is 3

当然,你可以给出相同的名字,但是 $不是必须的:

$ echo | awk -v VAR="$VAR" '{print "The value of VAR is " VAR}'
The value of VAR is 3

关于 awk 中的 $的注意事项: 与 bash、 Perl、 PHP 等不同,它不是变量名的一部分,而是 接线员

有两种方法可以将变量传递给 awk: 一种方法是在命令行参数中定义变量:

$ echo ${UL[*]}|awk -F, -v NUSR=$NUSR '{print $NUSR}'
SWATHI:SWATHI_NEW

另一种方法是使用 export将 shell 变量转换为环境变量,然后从 ENVIRON数组读取环境变量:

$ export NUSR
$ echo ${UL[*]}|awk -F, '{print $ENVIRON["NUSR"]}'
SWATHI:SWATHI_NEW

更新2016: OP 有逗号分隔的数据,并希望提取给定索引的条目。索引位于 shell 变量 NUSR中。NUSR的值传递给 awkawk的美元操作符提取该项。

注意,将 UL 声明为一个包含多个元素的数组,并在 bash中执行提取操作,然后完全取消 awk,这样会更简单。但是,这将使用基于0的索引。

UL=(AKHIL:AKHIL_NEW SWATHI:SWATHI_NEW)
NUSR=1
echo ${UL[NUSR]} # prints SWATHI:SWATHI_NEW

没有。您可以将 shell 变量的值传递给 awk 脚本,就像您可以将 shell 变量的值传递给 C 程序一样,但是您不能访问 awk 脚本中的 shell 变量,就像您不能访问 C 程序中的 shell 变量一样。和 C 一样,awk 不是 shell。参见 comp.unix.shell 常见问题解答 cfajohnson.com/shell/cus-FAQ-2.html#q24中的问题24。

编写代码的一种方法是:

UL="AKHIL:AKHIL_NEW,SWATHI:SWATHI_NEW"
NUSR=$(awk -F, -v ul="$UL" 'BEGIN{print gsub(FS,""); exit}')
echo "$NUSR"
echo "$UL" | awk -F, -v nusr="$NUSR" '{print $nusr}' # could have just done print $NF

但从你最初的出发点来看:

UL=(AKHIL:AKHIL_NEW,SWATHI:SWATHI_NEW)

声明 UL 为一个只有一个条目的数组时,您可能需要重新考虑您正在尝试做的事情,因为您可能采用了完全错误的方法。

Awk 和 Gawk 提供了包含所有导出环境变量的 ENVIRON关联数组。因此,在 awk 脚本中,可以使用 ENVIRON["VarName"]获取 VarName 的值,前提是在运行 awk 之前已经导出了 VarName。

注意: abc0是一个预定义的 awk 变量,而不是 shell 环境变量。

由于我没有足够的声誉来评论其他的答案,我必须在这里包括他们!

早期的答案显示 $ENVIRON是不正确的-语法将被 shell 扩展,并且可能导致什么也不扩展。

早些时候关于 c 无法访问环境变量的进一步评论是错误的。与上面所说的相反,C (和 C + +)可以使用 getenv("VarName")函数访问环境变量。许多其他语言也提供类似的访问(例如,Java: System.getenv(),Python: os.environ,Haskell System)。环境,...)。请注意,在所有情况下,对环境变量的访问都是只读的,因此不能更改程序中的环境变量并将该值返回给调用脚本。

不知道我是否理解你的问题。

但是让我们假设我们得到一个变量 number=3,我们想用它来代替 $3,在 awk 中我们可以用下面的代码来做到这一点

results="100 Mbits/sec 110 Mbits/sec 90 Mbits/sec"
number=3
speed=$(echo $results | awk '{print '"\$${number}"'}')

所以速度变量的值是110。

希望这个能帮上忙。

还有另一种方法,但它可能会造成巨大的混乱:

$ VarName="howdy" ; echo | awk '{print "Just saying '$VarName'"}'
Just saying howdy
$

因此,您暂时退出了单引号环境(这通常会阻止 shell 解释“ $”)来解释变量,然后返回到变量中。它的优点是相对简短。