I want to get positional parameters as arguments for my .sh file and I also want to get fields from a text file for awk. I've figured out that I need to use $1-$9 for both and its okay to use the same number $() in awk as a positioning parameter, it still works.
eg I call my shell script like this
./myProgram myFile.txt 1 2 3 4
Then within my shell script I want to use awk
to refer to fields in a text file like this, specifically 1,2:3,4 the last four fields.
0000000022:trevor:736:1,2:3,4
0000000223:john:73:5,6:7,8
0000002224:eliza:54:9,8:7,6
0000022225:paul:22:5,4:3,2
0000222226:chris:0:1,2:3,4
So I can go through the fields, however when I do because there are two types of field separators it doesn't seem to work.
My shell script so far:
#! /usr/bin/env bash
file="$1"
awk -F'[:,]' -v u1=$5 -v v1=$6 -v u2=$7 -v v2=$8 \ '{ print "u1 =", $u1 }' $1
awk -F'[:,]' -v u1=$5 -v v1=$6 -v u2=$7 -v v2=$8 \ '{ print "v1 =", $v1 }' $1
awk -F'[:,]' -v u1=$5 -v v1=$6 -v u2=$7 -v v2=$8 \ '{ print "u2 =", $u2 }' $1
awk -F'[:,]' -v u1=$5 -v v1=$6 -v u2=$7 -v v2=$8 \ '{ print "v2 =", $v2 }' $1
echo "Argument #1 =" $2
echo "Argument #2 =" $3
echo "Argument #3 =" $4
echo "Argument #4 =" $5
This is the output I get from terminal:
u1 = 1
u1 = 5
u1 = 9
u1 = 5
u1 = 1
v1 = awk: illegal field $(), name "v1"
input record number 1, file database.txt
source line number 1
u2 = awk: illegal field $(), name "u2"
input record number 1, file database.txt
source line number 1
v2 = awk: illegal field $(), name "v2"
input record number 1, file database.txt
source line number 1
Argument #1 = 1
Argument #2 = 2
Argument #3 = 3
Argument #4 = 4
I'm so close yet so far, I'm not sure why I'm not able to go further across the fields using my awk script?
Update : It seems that the OP's problem stemmed from confusion over the distinction between shell parameters ( $1
, $2
, ...) with input-field variables in Awk - which can look the same, but are entirely unrelated.
Specifically, the incorrect assumption was made that if n
parameters were passed to the shell script, Awk 's input-field numbering would start with n+1
.
The following snippet - originally written before the OP added more code to the question - demonstrates the interplay of shell parameters and Awk variables , followed by a detailed explanation.
Specifically, it defines Awk variables fi1
and fi2
based on the values of shell parameters $2
and $3
respectively, which contain 1-based field indices relative to the lines in file $file
.
Then, inside the Awk program, the field indices stored in fi1
and fi2
are used first as is (no $
prefix) to print their own value, and then to reference the corresponding input-line fields by prepending $
(variable references in Awk are NOT $
-prefixed - the $
is only used to refer to fields ).
#!/usr/bin/env bash
file="$1"
awk -F'[:,]' -v fi1=$2 -v fi2=$3 \
'{ print "Field #" fi1 " + field #" fi2 " =", $fi1 + $fi2 }' "$file"
awk
are separate worlds, and do not see each other's variables.
awk
, by accessing the ENVIRON
associative array, but you cannot see shell variables. awk
program by passing a double-quoted string with shell-variable references - which are expanded before awk
sees the program - but that gets confusing quickly and should be avoided. awk
to the shell is to have awk print to stdout and use a shell command substitution to capture the result in a shell variable. -v
option, as demonstrated above.
awk
, its variables are referenced without the $
prefix, and $
is only used to refer to input fields :
$fi1
, perhaps somewhat confusingly, therefore means: get the input field (prefix $
) whose index is stored in awk
variable fi1
(by contrast, using fi1
as is, without a prefix, would return the index ). awk
are always 1 -based , relative to each line of input.
awk
, $1
refers to the first field on the current input line , and even though it looks the same as the 1st script / function parameter in the shell , they have absolutely nothing to do with each other. $0
contains the entire current input line, and NF
contains the number (count) of input fields.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.