Set variable in current shell from awk

后端 未结 7 1892
花落未央
花落未央 2020-12-29 05:40

Is there a way to set a variable in my current shell from within awk?

I\'d like to do some processing on a file and print out some data; since I\'ll rea

相关标签:
7条回答
  • 2020-12-29 05:59

    echo "First arg: $1" for ((i=0 ; i < $1 ; i++)); do echo "inside" echo "Welcome $i times." cat man.xml | awk '{ x[NR] = $0 } END { for ( i=2 ; i<=NR ; i++ ) { if (x[i] ~ // ) {x[i+1]=" '$i'"}print x[i] }} ' > $i.xml done echo "compleated"

    0 讨论(0)
  • 2020-12-29 06:01

    Make awk print out the assignment statement:

    MYVAR=NewValue
    

    Then in your shell script, eval the output of your awk script:

    eval $(awk ....)
    # then use $MYVAR
    

    EDIT: people recommend using declare instead of eval, to be slightly less error-prone if something other than the assignment is printed by the inner script. It's bash-only, but it's okay when the shell is bash and the script has #!/bin/bash, correctly stating this dependency.

    The eval $(...) variant is widely used, with existing programs generating output suitable for eval but not for declare (lesspipe is an example); that's why it's important to understand it, and the bash-only variant is "too localized".

    0 讨论(0)
  • 2020-12-29 06:06

    Here's another way.

    This is especially useful when when you've got the values of your variables in a single variable and you want split them up. For example, you have a list of values from a single row in a database that you want to create variables out of.

    val="hello|beautiful|world" # assume this string comes from a database query
    read a b c <<< $( echo ${val} | awk -F"|" '{print $1" "$2" "$3}' )
    
    echo $a #hello
    echo $b #beautiful
    echo $c #world
    

    We need the 'here string' i.e <<< in this case, because the read command does not read from a pipe and instead reads from stdin

    0 讨论(0)
  • 2020-12-29 06:08

    To synthesize everything here so far I'll share what I find is useful to set a shell environment variable from a script that reads a one-line file using awk. Obviously a /pattern/ could be used instead of NR==1 to find the needed variable.

    # export a variable from a script (such as in a .dotfile)
    declare $( awk 'NR==1 {tmp=$1} END {print "SHELL_VAR=" tmp}' /path/to/file )
    export SHELL_VAR
    

    This will avoid a massive output of variables if a declare command is issued with no argument, as well as the security risks of a blind eval.

    0 讨论(0)
  • 2020-12-29 06:09
    $ echo "$var"
    
    $ declare $( awk 'BEGIN{print "var=17"}' )
    $ echo "$var"
    17
    

    Here's why you should use declare instead of eval:

    $ eval $( awk 'BEGIN{print "echo \"removing all of your files, ha ha ha....\""}' )
    removing all of your files, ha ha ha....
    
    $ declare $( awk 'BEGIN{print "echo \"removing all of your files\""}' )
    bash: declare: `"removing': not a valid identifier
    bash: declare: `files"': not a valid identifier
    

    Note in the first case that eval executes whatever string awk prints, which could accidentally be a very bad thing!

    0 讨论(0)
  • 2020-12-29 06:09

    You can't export variables from a subshell to its parent shell. You have some other choices, though, including:

    1. Make another pass of the file using AWK to count records, and use command substitution to capture the result. For example:

      FNR=$(awk 'END {print FNR}' filename)
      
    2. Print FNR in the subshell, and parse the output in your other process.
    3. If FNR is the same as number of lines, you can call wc -l < filename to get your count.
    0 讨论(0)
提交回复
热议问题