Converting a parameter to a floating point number in AWK - awk

I have this code that works fine:
time1=23245321;
ratio=0.9761;
time1=int(time1*ratio);
but I get it not to work when I transform the 'ratio' variable to a parameter passed to the script with the -v option - time1 results to be equal to 0 (zero).
awk -f script.awk -v ratio=0.9761
It seems ratio is no longer treated as a float. How can I solve this problem?

This works fine on my machine:
awk -v ratio=0.9761 '{
time1=23245321;
time1=int(time1*ratio);
print ratio,time1}' <(echo "Hello world!")
It returns:
0.9761 22689757

It was just a 'locale' issue: I should have called the script using
awk -f script.awk -v ratio=0,9761
because the comma is the decimal separator on my laptop

Related

awk command to print columns with colum data

cat file1.txt | awk -F '{print $1 "|~|" $2 "|~|" $3}' > file2.txt
I am using above command to filter first three columns from file1 and put into file.
But only getting the column names and not the column data.
How to do that?
|~| - is the delimiter.
file1.txt has values as :
a|~|b|~|c|~|d|~|e
1|~|2|~|3|~|4|~|5
11|~|22|~|33|~|44|~|55
111|~|222|~|333|~|444|~|555
my expedted output is :
a|~|b|~|c
1|~|2|~|3
11|~|22|~|33
111|~|222|~|333
With your shown samples, please try following awk code. You need to set field separator to |~| and remove starting space from lines, then print the lines.
awk -F'\\|~\\|' -v OFS='|~|' '{sub(/^[[:blank:]]+/,"");print $1,$2,$3}' Input_file
In case you want to keep spaces(which was in initial post before edit) then try following:
awk -F'\\|~\\|' -v OFS='|~|' '{print $1,$2,$3}' Input_file
NOTE: Had a chat with user in room and got to know why this code was not working for user because of gunzip -c file was being used wrongly, its output was being saved into a variable on which user was running awk program, so correcting that command generated right file and awk program ran fine on it. Adding this as a reference for future readers.
One approach would be:
awk -v FS="," -v OFS="|~|" '{gsub(/[|][~][|]/,","); sub(/^\s*/,""); print $1,$2,$3}' file1.txt
The approach simply replaces all "|~|" with a "," setting the output file separator to "|~|". All leading whitespace is trimmed with sub().
Example Use/Output
With your data in file1.txt, you would have:
$ awk -v FS="," -v OFS="|~|" '{gsub(/[|][~][|]/,","); sub(/^\s*/,""); print $1,$2,$3}' file1.txt
a|~|b|~|c
1|~|2|~|3
11|~|22|~|33
111|~|222|~|333
Let me know if this is what you intended. You can simply redirect, e.g. > file2.txt to write to the second file.
For such cases, my bash+awk script rcut comes in handy:
rcut -Fd'|~|' -f-3 ip.txt
The -F option enables fixed string input delimiter (which is given using the -d option). And by default, the output field separator will also be same as -d when -F is active. -f-3 is similar to cut syntax to specify first three fields.
For better speed, use hck command:
hck -Ld'|~|' -D'|~|' -f-3 ip.txt
Here, -L enables literal field separator and -D specifies output field separator.
Another benefit is that hck supports -z option to automatically handle common compressed formats based on filename extension (adding this since OP had an issue with compressed input).
Another way:
sed 's/|~|/\t/g' file1.txt | awk '{print $1"|~|"$2"|~|"$3}' > file2.txt
First replace the |~| delimiter, and use the default awk separator, then print columns what you need.

How to pass the argument into printf in awk?

format.awk is simple.
#! /usr/bin/awk
{
printf("%52s\\\n" ,$0);
}
The command is going to execute.
awk -f format.awk test
Now i want to make the number 52 in printf("%52s\\n" ,$0); as a varible.
awk -f format.awk -v n=52
If i want to pass argument 52 into format.awk,how to write the statement
printf("%ns\\\n" ,$0);
awk -f format.awk -v n=52 test
awk: run time error: improper conversion(number 1) in printf("%-ns\
")
FILENAME="test" FNR=2 NR=2
Yes you can, see the examples below:
kent$ awk 'BEGIN{a=3;printf "%.*f\n",a,10/3}'
3.333
kent$ awk 'BEGIN{a=7;printf "%.*f\n",a,10/3}'
3.3333333
The syntax is same as printf() of C, with *
Edit (add doc quote)
The C library printf’s dynamic width and prec capability (e.g.,
"%*.*s") is supported. Instead of supplying explicit width and/or prec
values in the format string, they are passed in the argument list.
Quote from gnu awk manual:
https://www.gnu.org/software/gawk/manual/html_node/Format-Modifiers.html
In awk, string interpolation does not work like that. You need to say
printf("%" n "s", $0)

how to search using variables in awk

I've this file test1 as follows
NAME1 04-03-2014
NAME2 04-04-2014
Now I'm able to get the o/p that I need when I execute from the command line but not when I use it as a variable. My awk version is 3.1.5
works from the cmd line: awk '$2 = /04-03-2014/' test1
doesn't work in the bash/ksh script:
export m=04 d=03 y=2014
awk -v m="$m" -v d="$d" -v y="$y" '$2 = /m-d-y/' test1 OR
awk -v m="$m" -v d="$d" -v y="$y" '$2 = m-d-y' test1 ### This replaces the 2nd field as -2010
I've used variables in awk before in printf statements to calculate numbers but the above example somehow doesn't seem to work for me. However, I tried a workaround i.e echo the awk cmd in a file and then executing the file as a script which gives me the desired o/p however I don't think this is the correct way of doing things and would appreciate if someone could give me a smarter way.
It's a guess but I bet you're trying to print every line where $2 is equal to a specific string constructed from your variables. If so that'd be:
awk -v m="$m" -v d="$d" -v y="$y" '$2 == m"-"d"-"y' file

simple awk string comparison unexpected result

In general string comparison, "A" > "a" is false.
However, I am getting unexpected result from this awk execution:
$ echo "A a"| awk '{if ($1 > $2) print "gt"; else print "leq"}'
gt
What am I missing?
Environment info:
$ uname -r -s -v -M
AIX 1 6 IBM,9110-510
$ locale
LANG=en_AU.8859-15
LC_COLLATE="en_AU.8859-15"
LC_CTYPE="en_AU.8859-15"
LC_MONETARY="en_AU.8859-15"
LC_NUMERIC="en_AU.8859-15"
LC_TIME="en_AU.8859-15"
LC_MESSAGES="en_AU.8859-15"
LC_ALL=
Diagnostics:
$ echo "A a"| awk '{print NF}'
2
Update It produces the correct result after setting LC_ALL=POSIX (thanks JS웃). Need to investigate further into this.
I am unable to reproduce this but you can force a string comparison by concatenating the operand with the null string:
echo "A a"| awk '{if ($1"" > $2"") print "gt"; else print "leq"}'
Note: Concatenating with any one operand should suffice.
Update:
As suspected the locale settings of OP were causing the issue. After setting LC_ALL=POSIX the issue was resolved.

variable declaration in awk command

I am facing the problem in awk command. Actually I used a variable DELETION_COMMAND and value of that variable is rm -rf. After that I am trying to execute the below line then it gives an error. While if am using the rm as a value of same variable DELETION_COMMAND. then it works fine.
awk '{print "'${DELETION_COMMAND}'"" ""'${COMPLETE_PATH}'""/"$1"/*"}' ${DB_FEED_FILE} > ${TEMP_FEED_FILE}
Error :
awk: {print "rm
awk: ^ unterminated string
Please suggest. Where am I wrong?
The highlighing already indicates your error. You put the awk expression between single quotes and then uses single quotes in the expression. Awk thinks your expression is this:
awk '{print "'
To solve this, escape the single quotes using a backslash.
Use the -v flag to pass shell vars to awk, and don't forget the quoting:
awk -v com="${DELETION_COMMAND}" -v path="${COMPLETE_PATH}" '{ print com, path, "/", $1, "/" }' "${DB_FEED_FILE}" > "${TEMP_FEED_FILE}"