Awk cross reference code not working on different platform - bash

I have a cross reference bash script using awk, however it works on my laptop but doesn't work on my other computer :s..
script example is :
"C:\cygwin\bin\gawk.exe" -F: "FNR==NR{a[$2]=$1;next} $1 in a{print a[$1] FS $2}" username.email.txt email.phone.txt > username.phone.txt
username.email input:
example:email#email.com
email.phone.txt input:
email#email.com:0123456789
username.phone output:
example:0123456789
so what happens here is if email is in > email.phone.txt, output > username & phone in username.phone.txt cross referencing between the 3 files.
this works fine on another laptop, however doesn't work on another computer.. i get a syntax error & invalid subscript expression.
Example of error:
gawk: cmd. line:1: FNR==NR{a[]=;next} in a{print a[] FS }
gawk: cmd. line:1: ^ syntax error
gawk: cmd. line:1: error: invalid subscript expression
gawk: cmd. line:1: FNR==NR{a[]=;next} in a{print a[] FS }
gawk: cmd. line:1: ^ syntax error
gawk: cmd. line:1: FNR==NR{a[]=;next} in a{print a[] FS }
gawk: cmd. line:1: ^ syntax error
gawk: cmd. line:1: FNR==NR{a[]=;next} in a{print a[] FS }
gawk: cmd. line:1: ^ syntax error
gawk: cmd. line:1: error: invalid subscript expression

Why use double-quotes for the body of awk commands? $1 has a special meaning when double-quoted, the values of $1 are being evaluated as positional arguments and are passed to awk, since they don't have values for it, that is why they are empty. Since awk sees an empty subscript array it complains it is not a valid array.
Simply single-quote it to solve the problem.
"C:\cygwin\bin\gawk.exe" -F: 'FNR==NR{a[$2]=$1;next} $1 in a{print a[$1] FS $2}' username.email.txt email.phone.txt > username.phone.txt
In general we single-quote the action(s) part to awk to pass them as literal strings to not let the shell do its parsing before passing it to awk. As mentioned single-quotes pass the string as-is without going through any expansion.
If you still want to go through the pain of using double-quotes, escape the dollar sign to deprive of its special meaning i.e. with an escaped character the dollar variables do not go through expansion ( not recommended in any way)
"C:\cygwin\bin\gawk.exe" -F: "FNR==NR{a[\$2]=\$1;next} \$1 in a{print a[\$1] FS \$2}" username.email.txt email.phone.txt > username.phone.txt

Related

escaping backslash and bracket on windows awk

I have an awk command that I want to use on cmd. The following command works well in bash, but fails on windows cmd:
echo errr | awk '/err/ { $0 = "\033[32m" $0 "\033[39m" }; 1'
I get the following error on windows:
awk: cmd. line:1: '/err/
awk: cmd. line:1: ^ invalid char ''' in expression
After going through some questions, I changed my command to:
echo errr | awk "/err/ { $0 = "\033[32m" $0 "\033[39m" }; 1"
but that gives me:
awk: cmd. line:1: /err/ { $0 = \033[32m $0 \033[39m }; 1
awk: cmd. line:1: ^ backslash not last character on line
awk: cmd. line:1: /err/ { $0 = \033[32m $0 \033[39m }; 1
awk: cmd. line:1: ^ syntax error
How can I port my command to work in cmd?
Standard advice when running awk on Windows:
a) don't do it, install cygwin and run awk from there instead
b) if "a" is not possible then create a file "foo.awk", store your script /err/ { $0 = "\033[32m" $0 "\033[39m" }; 1 in that, and then run it as awk -f foo.awk to avoid Windows nightmarish quoting rules.
instead of awk 'your commands' use awk -e 'your commands', there should be no error. I do not have windows to check. Will it be coloring the text? Read my comment below your question.
EDIT:
OK, now if you have version 6 in PowerShell, it should work coloring like this:
echo errr | awk -e "/err/ { $0 = '`e[32m' $0 '`e[39m'}; 1 "
If you have a different version windows, look for the correct escape sequence in the link I provided.

Bash-shell awk if-else with ternary operator grammar issue

cat file
AirIfLoadProfile trafficModelPrb ulDlRatioPerQci
EUtranCellTDD servOrPrioTriggeredErabAction 1
When I execute the command:
awk '($NF!~/^[0-9]+$/)?{printf("%s,%s,%s",$1,$2.$3)}:{printf("%s,%s,%s",$1,$2,$3)}' file
It comes to the error below:
awk: cmd. line:1: ($NF!~/^[0-9]+$/)?{printf("%s,%s,%s",$1,$2.$3)}:{printf("%s,%s,%s",$1,$2,$3)}
awk: cmd. line:1: ^ syntax error
awk: cmd. line:1: ($NF!~/^[0-9]+$/)?{printf("%s,%s,%s",$1,$2.$3)}:{printf("%s,%s,%s",$1,$2,$3)}
awk: cmd. line:1: ^ syntax error
Please help me find the format issue.
The right way:
awk '{ printf("%s %s%s%s\n",$1,$2,($NF~/^[0-9]+$/? " ":"."),$3) }' file
the 3rd format specifier %s accepts the result of the condition ($NF~/^[0-9]+$/? " ":".")
The output:
AirIfLoadProfile trafficModelPrb.ulDlRatioPerQci
EUtranCellTDD servOrPrioTriggeredErabAction 1

Bash-shell grammar issue about Ternary operator and printf function

cat file
chenghuanghuijia jidianzhong 100 E20128
pannybudaqiu gujihuihenwan -1
shuijiao buxihuan 20 E20138
huijiakan babamama 10
I want get the result that when the line contains E2[0-9]*$ , the end of the line will be printed, if the line not contain E2[0-9]*$, the end of the line will be printed NULL or \n.
Here is my code:
awk '{printf("%s\n",($NF~/E2[0-9]*$/? "E2.*$" : NULL))}' file
The output as below:
E2.*$
E2.*$
but I want to print E20128 & E20138, So I verified my code with deleting " "
awk '{printf("%s\n",($NF~/E2[0-9]*$/? E2.*$ : NULL))}' file
Then it comes the error:
awk: cmd. line:1: {printf("%s\n",($NF~/E2[0-9]*$/? E2.*$ : NULL))}
awk: cmd. line:1: ^ syntax error
awk: cmd. line:1: {printf("%s\n",($NF~/E2[0-9]*$/? E2.*$ : NULL))}
awk: cmd. line:1: ^ syntax error
awk: cmd. line:1: {printf("%s\n",($NF~/E2[0-9]*$/? E2.*$ : NULL))}
awk: cmd. line:1: ^ syntax error
So I think is the grammar issue of Ternary operator( _?x:y) or printf function.
please support me .
You can try this awk
awk '{$0=$NF}!/E2[0-9]*$/{$0=""}1' infile
{$0=$NF} : for each line replace the complete line by the last field.
!/E2[0-9]*$/ if the line not match the regex
{$0=""} : substitute the complete line by nothing
1 : print each line
With GNU sed:
sed '/.*\(E2[0-9]*\)$/s//\1/;//!s/.*//' file
/.*\(E2[0-9]*\)$: capture strings matching E2[0-9]* and output it using backreference (s//\1/)
//!: if there is no matching string, clear the line(s/.*//)
After think for a while ,below works:
awk '{printf("%s\n",($NF~/E2[0-9]*$/? $NF : NULL))}' file
If you just want to extract the E2..., a simple grep should be enough:
grep -o "E2[0-9]*$" file
-o is the option for extracting the matched pattern

Awk a space-separated file

When I awk the following, an error is encountered.
awk -F '$1' "2.\ 2006-07\ and\ 2007-08\ ERB\ IN.csv"
Here is the error:
awk: cmd. line:1: 2.\ 2006-07\ and\ 2007-08\ ERB\ IN.csv
awk: cmd. line:1: ^ backslash not last character on line
awk: cmd. line:1: 2.\ 2006-07\ and\ 2007-08\ ERB\ IN.csv
awk: cmd. line:1: ^ syntax error
If you want to print the first field in each line of the file, it should be:
awk '{print $1}' "2. 2006-07 and 2007-08 ERB IN.csv"
Since you left out the script argument to awk, it treated "2.\ 2006-07\ and\ 2007-08\ ERB\ IN.csv" as the script to execute. But that filename is not valid awk script syntax.

AWK syntax error - what's causing it?

I have simple bash script:
#!/bin/sh
column=${1:-1}
awk ' {colawk='$column'+2; print $colawk}'
awk '(x=4; print $x)'
But I have received error:
awk: (x=4; print $x)
awk: ^ syntax error
awk: cmd. line:1: (x=4; print $x)
awk: cmd. line:1: ^ unexpected newline or end of string
Why? Code in the previous line works.
An AWK program is a series of pattern action pairs, written as:
condition { action }
where condition is typically an expression and action is a series of commands.
print is not expression but a statement, so it's a syntax error as expected.
Your problem is with using parentheses instead of braces. Try:
awk '{x=4; print $x}'
instead, as in the following transcript:
pax$ echo a b c d e | awk '(x=4; print $x)'
awk: cmd. line:1: (x=4; print $x)
awk: cmd. line:1: ^ syntax error
awk: cmd. line:2: (x=4; print $x)
awk: cmd. line:2: ^ unexpected newline or end of string
pax$ echo a b c d e | awk '{x=4; print $x}'
d

Resources