Switch/Case Doesn't Work in Awk

Errors when executing switch/case in awk command in Ubuntu and Mac

Installing gawk solved my problem:

sudo apt-get install gawk

in mac:

sudo port install gawk

awk switch case with constant variable

Here is a way to sort it out using array in awk

awk -F, 'NR==1 {for (i=1;i<=NF;i++) {split($i,t," ");c[i]=t[2]}} NR>1 {for (j=1;j<i;j++) arr[(NR-1)FS c[j]]=$j+0} END {print arr[2 FS 1]}' file

Then END prints second row, column 1

This will for first file give 5

and 8 for second file


Some more readable:

awk -F, '
NR==1 { # get the column order
for (i=1;i<=NF;i++) { # loop trough all fields
split($i,tmp," ") # get the column number
col[i]=tmp[2]} # store the column order in col
}
NR>1 { # for all data do:
for (j=1;j<i;j++) # loop trough all element
arr[(NR-1)FS col[j]]=$j+0} # store data in array arr
END {
print arr[2 FS 1]} # print data from row 2 column 1
' file

awk variable assignment don't work under switch/case

Could you please try changing either(I am driving so haven't test it but should work if your code is not having any syntax issues)

head(clash, $2), $3 ,tail(clash, $4); ----> head("clash", $2), $3 ,tail("clash", $4);.

OR you could create a variable with awk -v value="clash" to keep it in variable format only. Then mention:

head(value, $2), $3 ,tail(value, $4);

@JoshuaLee. mentioning anything inside " double quotes means we are mentioniong value, if you want to have a variable and assign value to it use var="bla" or you want to pass directly anything without variable any value then use print "bla" for example I am mentioning here.

How to use --enable-switch in a bash script having AWK statement

You are using an extremely old version of gawk, switch statements were enabled by default as of 4.0 and we're now on 4.1.something. You're missing a LOT of extremely useful functionality (much more useful than a switch statement, see http://www.gnu.org/software/gawk/manual/gawk.html#Feature-History) so get a new gawk.

Having said that, you could keep using switch() after installing a new gawk but IMHO that's just not worth making your script gawk-specific for, just rewrite it as if-elses if that's the only gawk-specific feature you're using.

ignorecase in AWK

Add IGNORECASE = 1; to the beginning of your awk command like so:

bash-3.2$ echo "Create" | awk '/^create/;'
bash-3.2$ echo "Create" | awk 'IGNORECASE = 1;/^create/;'
Create

BREAK in AWK doesn't work

As indicated on the comments, changing break for exit can make it:

awk '{for (i=1;i<=NF;i++) {printf $i" "; if ($i~/TTT/) exit}}' file

Note you can delete the brackets around an action if there is only one:

if () {command}  <== equivalent ==>   if () command

but

if () {command1; command2} <== NOT equivalent ==>  if () command1; command2

Switch statement reverse using sed

With GNU awk for multi-char RS:

$ gawk -vRS="^$" -vORS= '{$0=gensub(/(case \()([^)]+)(\):\s*return )(\S+);/,"\\1\\4\\3\\2;","g")}1' file  
switch (argument0) {
case (0):
return "Goblin";
break;
case (1):
return "Fang";
break;
...
}

Liberally sprinkle \s*s in the regexp if/when white space can occur.

AWK - Processing multiple file through for loop and conditional check

Firt way(GNU awk, if you don't have GNU awk please leave comment):

awk -F, 'NR==FNR{y=substr($12,3,4); a[$3]=y FS $3 FS $4; b[$5]=y FS $5 FS $6; c[$9]=y FS $9 FS $10; next} FNR==1{printf nl;nl="\n"} match(FILENAME, /myfilename_([A-Z]*)/, f){NF=6;switch(f[1]){case "WEEK": $1=a[$1];break; case "MONTH": $1=b[$1];break; case "HALF": $1=c[$1];}}1' OFS=, calendar_file myfilename_{WEEK,MONTH,HALF}.csv

Multiple lines for readability:

awk -F, '
NR==FNR{
y=substr($12,3,4);
a[$3]=y FS $3 FS $4;
b[$5]=y FS $5 FS $6;
c[$9]=y FS $9 FS $10;
next
}
FNR==1{printf nl;nl=ORS} ## The newlines between sectors, if you do not need those newlines then remove this line.
match(FILENAME, /myfilename_([A-Z]*)/, f){
NF=6; ## To limit results for 6 columns only, can remove it here.
switch(f[1]){
case "WEEK":
$1=a[$1];
break;
case "MONTH":
$1=b[$1];
break;
case "HALF":
$1=c[$1];
}
}1' OFS=, calendar_file myfilename_{WEEK,MONTH,HALF}.csv

An update to it:

awk -F, '
NR==FNR{
y=substr($12,3,4);
a[$3]=y FS $3 FS $4;
b[$5]=y FS $5 FS $6;
c[$9]=y FS $9 FS $10;
next
}
FNR==1{printf nl;nl=ORS} ## The newlines between sectors, if you do not need those newlines then remove this line.
match(FILENAME, /myfilename_([A-Z]*)/, f){
NF=6; ## To limit results for 6 columns only, can remove in your case.
$1 = f[1]=="WEEK" ? a[$1] : ( f[1]=="MONTH" ? b[$1] : (f[1]=="HALF" ? c[$1] : $1) )
}1' OFS=, calendar_file myfilename_{WEEK,MONTH,HALF}.csv

Second Way, more concise and without using switch (also GNU awk):

awk -F, '
NR==FNR{
y=substr($12,3,4);
a[$3 "WEEK"]=y FS $3 FS $4;
a[$5 "MONTH"]=y FS $5 FS $6;
a[$9 "HALF"]=y FS $9 FS $10;
next
}
FNR==1{printf nl;nl=ORS} ## The newlines between sectors, if you do not need those newlines then remove this line.
match(FILENAME, /myfilename_([A-Z]*)/, f){
$1=a[$1 f[1]];
}1' OFS=, calendar_file myfilename_{WEEK,MONTH,HALF}.csv

Third way: If your data are all corresponding to their filenames, like you showed in your samples, there's a third way which removes the need of match, so it can work on other awks:

awk -F, '
NR==FNR{
y=substr($12,3,4);
a[$3 "w"]=y FS $3 FS $4;
a[$5 "m"]=y FS $5 FS $6;
a[$9 "h"]=y FS $9 FS $10;
next
}
FNR==1{printf nl;nl=ORS} ## The newlines between sectors, if you do not need those newlines then remove this line.
$1~/^([wmh])[0-9]{2}_[0-9]{4}/{ ## Check first fields to make sure it matches, the checking is optional if your data is all like you showed.
$1=a[$1 substr($1,1,1)]
print
}' OFS=, calendar_file myfilename_{WEEK,MONTH,HALF}.csv

Given a second thought, based on your data-filename relations, there's actually no need to check the first letter (nor the filename):

awk -F, '
NR==FNR{
y=substr($12,3,4);
a[$3]=y FS $3 FS $4;
a[$5]=y FS $5 FS $6;
a[$9]=y FS $9 FS $10;
next
}
FNR==1{printf nl;nl=ORS} ## The newlines between sectors, if you do not need those newlines then remove this line.
{ ## Add $1~/^([wmh])[0-9]{2}_[0-9]{4}/ to the beginning of this line if you want to check and make sure first column.
$1=a[$1]
}1' OFS=, calendar_file myfilename_{WEEK,MONTH,HALF}.csv


Related Topics



Leave a reply



Submit