Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

awk variable assignment statement explanation needed

Tags:

awk

gawk

ok, straight to the point, here is the codes, I formatted the codes a little to make it easy to read:

awk '{
t=$0   ; 
$0=t   ; $0=//           ; print "$0=//           ; value of $0 is ",$0
$0=t   ; $0=/./          ; print "$0=/./          ; value of $0 is ",$0
$0=t   ; $0=/*/          ; print "$0=/*/          ; value of $0 is ",$0
$0=t   ; $0=/**/         ; print "$0=/**/         ; value of $0 is ",$0
$0=t   ; $0=/[0-9]/      ; print "$0=/[0-9]/      ; value of $0 is ",$0
$0=t   ; $0=/[a-z]/      ; print "$0=/[a-z]/      ; value of $0 is ",$0
$0=t   ; $0=/[0-9][a-z]/ ; print "$0=/[0-9][a-z]/ ; value of $0 is ",$0
$0=t   ; $0=/5/          ; print "$0=/5/          ; value of $0 is ",$0
$0=t   ; $0=/55/         ; print "$0=/55/         ; value of $0 is ",$0
$0=t   ; $0=/x/          ; print "$0=/x/          ; value of $0 is ",$0
$0=t   ; $0=/5x/         ; print "$0=/5x/         ; value of $0 is ",$0
$0=t   ; $0=/x5/         ; print "$0=/x5/         ; value of $0 is ",$0
$0=t   ; $0=/xoo/        ; print "$0=/xoo/        ; value of $0 is ",$0
$0=t   ; $0=/500/        ; print "$0=/500/        ; value of $0 is ",$0
}'<<<"5x"

I got this output:

$0=//           ; value of $0 is  1
$0=/./          ; value of $0 is  1
$0=/*/          ; value of $0 is  0
$0=/**/         ; value of $0 is  1
$0=/[0-9]/      ; value of $0 is  1
$0=/[a-z]/      ; value of $0 is  1
$0=/[0-9][a-z]/ ; value of $0 is  1
$0=/5/          ; value of $0 is  1
$0=/55/         ; value of $0 is  0
$0=/x/          ; value of $0 is  1
$0=/5x/         ; value of $0 is  1
$0=/x5/         ; value of $0 is  0
$0=/xoo/        ; value of $0 is  0
$0=/500/        ; value of $0 is  0

I cannot understand why I got this output. I thought awk would complain about the assignment statement, but it didn't... It seems that awk is doing weird regex matching check when I did $0=/xxx/? that is, $0=/pattern/ is same as $0=$0~/pattern/?

then I did this test:

kent$  echo "xx"|awk '{y="777";y=/x/;print y}'                                                                                                                              
1

kent$  echo "xx"|awk '{y="777";y=/7/;print y}'                                                                                                                              
0

so it seems, foo=/pattern/ is same as foo=$0~/pattern/

but I am not sure... cannot find the info in document/man page.

I found it when I was answering an awk question here @ SO.

I tested with my awk:

kent$  awk --version|head -1
GNU Awk 4.1.0, API: 1.0 (GNU MPFR 3.1.2, GNU MP 5.1.2)

I appreciate if someone could explain me. Thanks in advance.

EDIT

after doing more tests, it turns out (again, not sure, since I didn't find it in document), within {...}, the /pattern/ alone is short form of $0~/pattern/ same as outside the {...}, like /patter/{do something} . so we could do:

kent$  echo "xx"|awk '{if(/x/)print "ok"}'                                                                                                                                  
ok

I don't know if it is a standard feature of awk script syntax. and if it works for all awk implementation. I am still searching manual and man page...

like image 531
Kent Avatar asked Sep 13 '13 21:09

Kent


People also ask

What is awk '{ print $1 }'?

awk '{print $1}' information. txt prints the first column. Then the output of that command (which you saw earlier on) is piped, using the pipe symbol | , to the head command, where its -1 argument selects the first line of the column. If you wanted two lines printed, you'd do: awk '{print $1}' information.txt | head -2.

Which allows assignment to a variable before program execution in awk?

Assignment Operators The last Awk feature we shall cover is assignment operators, there are several assignment operators in Awk and these include the following: *= : multiplication assignment operator. += : addition assignment operator. /= : division assignment operator.

What does $1 $2 indicate in awk file?

The awk variables $1 or $2 through $nn represent the fields of each record and should not be confused with shell variables that use the same style of names. Inside an awk script $1 refers to field 1 of a record; $2 to field 2 of a record.


2 Answers

/regexp/ is just shorthand for $0 ~ /regexp/

var = ($0 ~ /regexp/) assigns var the result of the comparison, 1 for true, zero otherwise.

$0 = ($0 ~ /regexp/) assigns $0 the result of the comparison of $0 and /regexp/

$0 = ($0 ~ //) assigns $0 the result of looking for an empty string in $0, which there always is, so the condition is true so the result is 1

$0 = // does the same

$0 = /*/ is looking for a literal * in $0, which there isn't so the result is zero.

$0 = /**/ is looking for a literal * repeated ZERO or more times in $0, which there are zero of them so that result is 1.

No mystery, nothing weird...

like image 90
Ed Morton Avatar answered Sep 21 '22 11:09

Ed Morton


There is not mystery here you are just setting the value of $0 to the value of the evaluated regular expression match. The right hand side is evaluated first, if the line matches the regular expression match the results is True i.e. 1, else the results is False i.e. 0.

like image 29
Chris Seymour Avatar answered Sep 19 '22 11:09

Chris Seymour