我们可以在AWK中使用shell变量,例如$VAR
而不是$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,我们收到很多导入请求。我正在尝试使用脚本自动化它。该脚本将找出转储中的用户并提示需要加载转储的用户。
假设转储有两个用户AKHIL
,SWATHI
(转储中可能有用户,我想导入更多用户)。我想将转储导入新用户AKHIL_NEW
和SWATHI_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。
答案 0 :(得分:70)
是的,您可以在awk中使用 shell变量。有很多方法可以做到,但我最喜欢的是使用-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等不同,它不是变量名称的一部分,而是an operator。
答案 1 :(得分:16)
Awk和Gawk提供ENVIRON关联数组,该数组包含所有导出的环境变量。所以在你的awk脚本中你可以使用ENVIRON [“VarName”]来获取VarName的值,只要在运行awk之前导出了VarName。
注意ENVIRON是预定义的awk变量,而不是shell环境变量。
由于我没有足够的声誉来评论其他答案,我必须将它们包含在这里!
早期的答案显示$ ENVIRON是不正确的 - 该语法将由shell扩展,并可能导致扩展为空。
之前关于C无法访问环境变量的更多评论是错误的。与上述相反,C(和C ++)可以使用getenv(“VarName”)函数访问环境变量。许多其他语言提供类似的访问(例如,Java:System.getenv(),Python:os.environ,Haskell System.Environment,...)。请注意,在所有情况下,对环境变量的访问都是只读的,您无法更改程序中的环境变量并将该值返回给调用脚本。
答案 2 :(得分:12)
有两种方法可以将变量传递给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
的值传递给awk
,而awk
的美元运算符会提取该项目。
请注意,将UL声明为包含多个元素的数组更简单,并在bash
中进行提取,并将awk
完全取出等式。然而,这使用基于0的索引。
UL=(AKHIL:AKHIL_NEW SWATHI:SWATHI_NEW)
NUSR=1
echo ${UL[NUSR]} # prints SWATHI:SWATHI_NEW
答案 3 :(得分:5)
还有另一种方式,但它可能会造成巨大的混乱:
$ VarName="howdy" ; echo | awk '{print "Just saying '$VarName'"}'
Just saying howdy
$
因此,您暂时退出单引号环境(通常会阻止shell解释&#39; $&#39;)来解释变量然后返回到它。它具有相对简短的优点。
答案 4 :(得分:2)
不确定我是否理解你的问题。
但是我们假设我们得到了一个变量number=3
,我们希望使用它而不是$3
,在awk中我们可以使用以下代码来做到这一点
results="100 Mbits/sec 110 Mbits/sec 90 Mbits/sec"
number=3
speed=$(echo $results | awk '{print '"\$${number}"'}')
因此速度变量将获得值110。
希望这有帮助。
答案 5 :(得分:-1)
没有。您可以将shell变量的值传递给awk脚本,就像您可以将shell变量的值传递给C程序一样,但是您无法访问awk脚本中的shell变量,只能访问shell变量。 C程序。像C一样,awk不是shell。请参阅cfajohnson.com/shell/cus-faq-2.html#Q24上的comp.unix.shell常见问题解答中的问题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只是一个只有一个条目的数组,你可能想重新考虑你正在尝试做的事情,因为你可能有完全错误的方法。