2
# mkfifo inp out
# bc -ql  <inp  >out  &
[1] 6766
#
# exec 3>inp  4<out
# echo "scale=3; 4/5;" >&3
# read a <&4; echo $a
.800
#
# awk ' BEGIN { printf("4/5\n") >"/dev/fd/3"; exit 1;} '
# read a <&4; echo $a
.800
#
# awk ' BEGIN { printf("4/5\n") >"/dev/fd/3"; exit 1;} '
# awk ' BEGIN { getline a <"/dev/fd/4"; printf("%s\n", a); } '
^C

In BASH environment I can communicate with bc program using fifo. But in awk I can write but no read with getline function. How can I read from "/dev/fd/4" in awk.

My awk version is: mawk 1.3.3 Nov 1996, Copyright (C) Michael D. Brennan

Thanks Laci

Continued:

I did some further experiment and I summarize my result. Awk script language suits best for my task, and I need to use "bc" because I have to count with very long numbers (about 100 digits). The next two scripts show that using named pipe is faster than unnamed (about 83 times).

1) With unnamed pipe:

# time for((i=6000;i;i--)); do a=`echo "$i/1"|bc -ql`; done
real    0m13.936s

2) With named pipe:

# mkfifo in out
# bc -ql <in >out &
# exec 3>in 4<out
#
# time for((i=500000;i;i--)); do echo "$i/1" >&3; read a <&4; done
real    0m14.391s

3) In the awk environment the bc usage is a bit slower (about 18 times) than in bash but it works this way:

# time awk ' BEGIN {
#               for(i=30000;i;i--){
#                   printf("%d/1\n",i) >"/dev/fd/3";
#                   system("read a </dev/fd/4; echo $a >tmp_1");
#                   getline a <"tmp_1"; close("tmp_1");}
#                  } '
real    0m14.178s

4)What can be the problem when I try to do accordig to "man awk" ? :

# awk ' BEGIN {
#         for(i=4;i;i--){
#         printf("%d/1\n",i) >"/dev/fd/3"; system("sleep .1");
#        "read a </dev/fd/4; echo $a" | getline a ;print a;}
#      } '
4.000
4.000
4.000
4.000

The above "awk" script was able to pick up only the first number from the pipe. The other three numbers remained in the pipe. These will be visible when I'm reading the pipe after the above awk script.

# for((;;)); do read a </dev/fd/4; echo $a; done
3.000
2.000
1.000

Thanks for gawk.

2
  • Works fine with gawk. Fails with mawk. Which awk are you using? Commented Feb 18, 2015 at 22:30
  • You should include that in your question! I have the same mawk and it fails like you. But with gawk it works fine. Commented Feb 21, 2015 at 19:25

2 Answers 2

2

It sounds like you're looking for gawk's co-process ability, see http://www.gnu.org/software/gawk/manual/gawk.html#Getline_002fCoprocess. Given awks support of math functions, though, I wonder why you'd want to use bc...

Sign up to request clarification or add additional context in comments.

1 Comment

bc does have multiple precision.
0

Try:

mkfifo inp out
bc -l  <inp  >out  &
awk ' BEGIN { printf("4/5\n"); exit 0;} ' > inp
read a < out; echo $a

awk ' BEGIN { printf("4/5\n"); exit 0;} ' > inp

awk ' BEGIN { getline a; printf("%s\n", a); exit 0 } ' < out

rm inp 
rm out

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.