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

Akh*_*nnu 47 awk

我们可以使用shell变量AWK像$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}'
Run Code Online (Sandbox Code Playgroud)

实际上我是一个oracle DBA,我们得到了很多导入请求.我正在尝试使用脚本自动化它.该脚本将查找转储中的用户并提示需要加载转储的用户.

假设转储有两个用户AKHIL,SWATHI(有可在转储可能的用户,我希望进口更多的用户数).我想将转储导入新用户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[*]} 
Run Code Online (Sandbox Code Playgroud)

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

bra*_*zzi 74

是的,你可以在awk中使用shell变量.有很多方法可以做到,但我最喜欢的是用-v标志定义一个变量:

$ echo | awk -v my_var=4 '{print "My var is " my_var}'
My var is 4
Run Code Online (Sandbox Code Playgroud)

只需将环境变量作为参数传递给-v标志即可.例如,如果您有此变量:

$ VAR=3
$ echo $VAR
3
Run Code Online (Sandbox Code Playgroud)

用这种方式:

$ echo | awk -v env_var="$VAR" '{print "The value of VAR is " env_var}'
The value of VAR is 3
Run Code Online (Sandbox Code Playgroud)

当然,你可以给出相同的名字,但是$没有必要:

$ echo | awk -v VAR="$VAR" '{print "The value of VAR is " VAR}'
The value of VAR is 3
Run Code Online (Sandbox Code Playgroud)

关于$awk的注释:与bash,Perl,PHP等不同,它不是变量名称的一部分,而是一个运算符.

  • 答案是不!您可以将shell变量的值传递给awk脚本,就像您可以将shell变量的值传递给C程序一样,但是您无法访问awk脚本中的shell变量,只能访问shell变量. C程序.像C一样,awk不是shell. (7认同)
  • @EdMorton 您可以在 C 中访问环境变量。这就是它们最初的设计目的。 (3认同)
  • 谢谢你,@brandizzi。我觉得 EM 有点迂腐。 (2认同)

gra*_*son 19

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

注意ENVIRON是预定义的awk变量,而不是shell环境变量.

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

早期的答案显示$ ENVIRON是不正确的 - 该语法将由shell扩展,并可能导致扩展为空.

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

  • +1,但这是完全不正确的:“在所有情况下,对环境变量的访问都是只读的”。您可以更改环境,但只能更改当前程序或当前程序启动的程序。也就是说,您的最后一行是正确的,您不能通过外部程序更改当前Shell的环境。另一个要注意的是,shell变量与环境变量不同,尽管对于shell用户而言,它们看起来很相似并且以相同的方式访问(至少在`sh`和相似的shell中)。 (2认同)

Jon*_*oni 12

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

$ echo ${UL[*]}|awk -F, -v NUSR=$NUSR '{print $NUSR}'
SWATHI:SWATHI_NEW
Run Code Online (Sandbox Code Playgroud)

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

$ export NUSR
$ echo ${UL[*]}|awk -F, '{print $ENVIRON["NUSR"]}'
SWATHI:SWATHI_NEW
Run Code Online (Sandbox Code Playgroud)

2016年更新: OP具有逗号分隔数据,并希望提取给定索引的项目.索引在shell变量中NUSR.值NUSR传递给awk,并且awk'美元运算符提取项.

请注意,将UL声明为包含多个元素的数组并进行提取bashawk完全取出等式会更简单.然而,这使用基于0的索引.

UL=(AKHIL:AKHIL_NEW SWATHI:SWATHI_NEW)
NUSR=1
echo ${UL[NUSR]} # prints SWATHI:SWATHI_NEW
Run Code Online (Sandbox Code Playgroud)

  • 不应该第一个是"打印NUSR"而不是? (2认同)
  • 有两种以上的方式.请参阅http://cfajohnson.com/shell/cus-faq-2.html#Q24上的comp.unix.shell常见问题解答中的问题24. (2认同)

Phi*_*rns 6

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

$ VarName="howdy" ; echo | awk '{print "Just saying '$VarName'"}'
Just saying howdy
$
Run Code Online (Sandbox Code Playgroud)

因此,您暂时退出单引号环境(通常会阻止shell解释'$')来解释变量,然后再返回它.它具有相对简短的优点.