AWK print specific column if chosen column is only numeric else print another column AIX - awk

Is it possible to use an awk if condition to print a specific column if the chosen column is only values or characters?
below is an example:
echo "This is example test 1 for VAL1 value = int or VAL2 = string" | awk '{if ($5 == [0-9]) print $10 else print $14}'
OR:
echo "This is example test one for VAL1 value = int or VAL2 = string" | awk '{if ($5 == [A-Z]) print $14; else print $10}'
The two examples above is determening from the awk if column 5 is all values or numbers and print a specific column based on column if whether it is only numbers or has string characters. In my example it can only be one or the either and not both mixed with numbers and characters.
How is it possible to do this using an awk?

Here is the problem:
$5 == [0-9]
In awk we use == operator for equality not for regex evaluation. We must use ~ for regex and also enclose a regex in /.../ notation.
So all of these awk solutions should work for you:
# check presence of a digit anywhere in the fifth field
awk '{print ($5 ~ /[0-9]/ ? $10 : $14)}'
# check if fifth field contains 1+ digits only
awk '{print ($5 ~ /^[0-9]+$/ ? $10 : $14)}'
# awk shorthand to check if $5 is numeric value
awk '{print ($5+0 == $5 ? $10 : $14)}'
Similarly to check an uppercase character use:
awk '{print ($5 ~ /[A-Z]/ ? $14 : $10)}'

Related

awk conditional statement based on a value between colon

I was just introduced to awk and I'm trying to retrieve rows from my file based on the value on column 10.
I need to filter the data based on the value of the third value if ":" was used as a separator in column 10 (last column).
Here is an example data in column 10. 0/1:1,9:10:15:337,0,15.
I was able to extract the third value using this command awk '{print $10}' file.txt | awk -F ":" '/1/ {print $3}'
This returns the value 10 but how can I return other rows (not just the value in column 10) if this third value is less than or greater than a specific number?
I tried this awk '{if($10 -F ":" "/1/ ($3<10))" print $0;}' file.txt but it returns a syntax error.
Thanks!
Your code:
awk '{print $10}' file.txt | awk -F ":" '/1/ {print $3}'
should be just 1 awk script:
awk '$10 ~ /1/ { split($10,f,/:/); print f[3] }' file.txt
but I'm not sure that code is doing what you think it does. If you want to print the 3rd value of all $10s that contain :s, as it sounds like from your text, that'd be:
awk 'split($10,f,/:/) > 1 { print f[3] }' file.txt
and to print the rows where that value is less than 7 would be:
awk '(split($10,f,/:/) > 1) && (f[3] < 7)' file.txt

awk compare two columns in same file with letters in one column

how todo column matching in same file. for e.g compare server and FQDN column. FQDN column has extra words so i couldn't find way to strip.
"server","cpu","memory","disk","FQDN"
"host1",4,32,100,"host2.xxx.com"
"host2",2,10,20,"host2.xxx.com"
"host3",6,4,100,"host1.xxx.com"
"host4",2,10,30,"host4.xxx.com"
"host5",3,6,32,"host3.xxx.com"
awk -F, '$1 ~ /$5/' test.csv
expected results:
"host1",4,32,100,"host2.xxx.com"
"host3",6,4,100,"host1.xxx.com"
"host5",3,6,32,"host3.xxx.com"
Test a substring of $5 that has same length as $1:
awk -F, 'substr( $5, 1, length($1) ) == $1' test.csv
Your "expected results" show lines where these fields don't match. If that's what you want, do the same transformation but test for inequality instead:
awk -F, 'substr( $5, 1, length($1) ) != $1' test.csv
For getting matches: try following.
awk -F'[,.]' '$1==$5' Input_file
For getting NON matching: try following.
awk -F'[,.]' '$1!=$5' Input_file
OR to remove headers in output try:
awk -F'[,.]' 'FNR>1 && $1!=$5' Input_file
Explanation: Setting field separator as , or . for all lines in Input_file and then simply comparing $1 and $5, for matching case using == condition and for NON matching case using != condition.

awk / gawk printf when variable format string, changing zero to dash

I have a table of numbers I am printing in awk using printf.
The printf accomplishes some truncation for the numbers.
(cat <<E\OF
Name,Where,Grade
Bob,Sydney,75.12
Sue,Sydney,65.2475
George,Sydney,84.6
Jack,Sydney,35
Amy,Sydney,
EOF
)|gawk 'BEGIN{FS=","}
FNR==1 {print("Name","Where","Grade");next}
{if ($3<50) {$3=0}
printf("%s,%s,%d \n",$1,$2,$3)}'
This produces:
Name Where Grade
Bob,Sydney,75
Sue,Sydney,65
George,Sydney,84
Jack,Sydney,0
Amy,Sydney,0
What I want is to display scores which are less than 50, or missing, as a dash ("-").
Name Where Grade
Bob,Sydney,75
Sue,Sydney,65
George,Sydney,84
Jack,Sydney,-
Amy,Sydney,-
This requires the 3rd string format in printf change from %d to %s.
So in some rows, the third column should be a value, and in some rows, the third column should be a string. How can I tell this to GAWK? Or should I just pipe through another awk to re-format?
$ gawk 'BEGIN{FS=","}
FNR==1 {print("Name","Where","Grade");next}
{if ($3<50) {$3="-"} else {$3=sprintf("%d", $3)}
printf("%s,%s,%s \n",$1,$2,$3)}' ip.txt
Name Where Grade
Bob,Sydney,75
Sue,Sydney,65
George,Sydney,84
Jack,Sydney,-
Amy,Sydney,-
use if-else to assign value to $3 as needed
sprintf allows to assign result of formatting to a variable
for this case, you could use int function as well
now printf will have %s for $3 as well
Assuming you missed the commas for the header and space after third column is not needed, you could do this with a simple one-liner
$ awk -F, -v OFS=, 'NR>1{$3 = $3 < 50 ? "-" : int($3)} 1' ip.txt
Name,Where,Grade
Bob,Sydney,75
Sue,Sydney,65
George,Sydney,84
Jack,Sydney,-
Amy,Sydney,-
?: ternary operator is alternate for if-else
1 is an awk idiom to print contents of $0

Awk Field number of matched pattern

I was wondering if there's a built in command in awk to get the field number of the phrase that you just matched.
Banana is yellow.
awk {
/yellow/{ for (i=1;i<=NF;i++) if($i ~/yellow/) print $i}'
Is there a way to avoid writing the loop?
Your command doesn't work when I test it. Here's my version:
echo "banana is yellow" | awk '{for (i=1;i<=NF;i++) if($i ~/yellow/) print i}'
The output is :
3
As far as I know, there's no such built-in feature, to improve your command, the pattern match /yellow/ at the beginning is not necessary, and also $i will print the matching field other than the field number that you need.
Alternatively, you can use an array to store each field and its corresponding index number, and then print field by arr["yellow"]
If the input string is a oneline string you can set the record delimiter to the field delimiter. Doing so you can use NR to print the position:
awk 'BEGIN{RS=FS}/yellow/{print NR}' <<< 'banana is yellow'
3

Awk editing with field delimiter

Imagine if you have a string like this
Amazon.com Inc.:181,37:184,22
and you do awk -F':' '{print $1 ":" $2 ":" $3}' then it will output the same thing.
But can you declare $2 in this example so it only outputs 181 and not ,37?
Thanks in advance!
You can change the field separator so that it contains either : or ,, using a bracket expression:
awk -F'[:,]' '{ print $2 }' file
If you are worried that , may appear in the first field (which will break this approach), you could use split:
awk -F: '{ split($2, a, /,/); print a[1] }' file
This splits the second field on the comma and then prints the first part. Any other fields containing a comma are unaffected.