passing bash variable for awk column specifier

前端 未结 2 1605
無奈伤痛
無奈伤痛 2021-01-24 06:35

There are loads of threads about passing a shell variable to awk, and I\'ve figured that out easily enough, but the variable I want to pass is the column specifier variable (

2条回答
  •  野性不改
    2021-01-24 07:12

    When you pass awk -v a="$field", the specification of the awk variable a is only good for that single awk command. You can't expect a to be available in a completely different invocation of awk.

    Thus, you need to put it in-place directly:

    $ bashvar="2"
    $ echo 'foo bar baz' | awk -v awkvar="$bashvar" '{print $awkvar}'
    bar
    

    Or in your case:

    field=1
    awk -v a="$field" '
    NR==FNR {
      o[FNR]=$a;
      next;
    }
    
    { t[$1] = $0 }
    
    END {
      for(x=1; x<=FNR; x++) {
        y=o[x]
        printf("%s\t%s\n", y, t[y])
      }
    }' "$keyfile" "$filetosort"
    

    Points of note:

    • Our printf here is emitting both the key and the value, so there's no need to use paste to put the keyfile values back in.
    • $a is used to treat the awk variable a (assigned from shell variable field) as a variable name itself, and to perform an indirect reference -- thus, looking up the relevant column number.
    • Always, always quote your shell variables on expansion. Otherwise, you have no way of knowing how many argument to awk will be generated by the expansion of $keyfile -- it could be 0 (if there are no characters in the string not found in IFS); it could be 1, but it could also be a completely unbounded number (input file.txt would become two arguments, input and file.txt; * input * .txt would have each * replaced with a list of files).

提交回复
热议问题