I just found out about piping stdout into Perl, and I was amazed that you could even do this:
[user@folder] $ echo print 1/3 | perl
0.33333[user@folder] $
From what I understand, you're putting the print command into Perl, and doing a floating point calculation using Perl's code. Please correct me. However, every time I do this, I get an answer that has no newline character. I've searched everywhere and I just can't keyword the terms specific enough to create the answer.
Here's a link to what I'm talking about, under poster Thor: How do I use floating-point division in bash?
He gave an amazing answer, but I couldn't comment or message the user, so I've decided to create a new question here.
I'm still trying to wrap my head around how this is working, variables as well.
$ three=3
$ echo $three/3 | perl
1[user@folder] $
Bonus question:
It started out as me just trying to get bash to output floating point numbers in arithmetic operations. I don't get why bc
can't return a float. Supposedly it can, but it just isn't working for me.
Ideally:
$ echo 1/3 | bc
0
$
should return .333 and not 0. I'm delegating to a tool, bc
, and bc
is supposed to be able to do floats. I just don't understand what's going on.
Use the -l
option (see perldoc perlrun
):
$ echo print 1/3 | perl -l
0.333333333333333
$
It adds newlines automatically. The documentation says:
-l[octnum]
enables automatic line-ending processing. It has two separate effects. First, it automatically chomps
$/
(the input record separator) when used with-n
or-p
. Second, it assigns$\
(the output record separator) to have the value of octnum so that any print statements will have that separator added back on. If octnum is omitted, sets$\
to the current value of$/
. For instance, to trim lines to 80 columns:perl -lpe 'substr($_, 80) = ""'
Note that the assignment
$\ = $/
is done when the switch is processed, so the input record separator can be different than the output record separator if the-l
switch is followed by a-0
switch:gnufind / -print0 | perl -ln0e 'print "found $_" if -p'
This sets
$\
to newline and then sets$/
to the null character.
The shell expands shell variables, so there shouldn't be a surprise at this:
$ three=3
$ echo print $three/3 | perl -l
1
$ echo print $three/3
print 3/3
$
For your bonus question:
$ echo 1/3 | bc -l
.33333333333333333333
$
It is pure fluke that the option is -l
again. This time, it means 'load the library', and coincidentally sets the scale
to 20, which is why there are 20 decimal digits shown.
Incidentally, a quick way to get π to a large number of decimal places is:
$ echo '4*a(1)' | bc -l
3.14159265358979323844
$ echo 'scale=40; 4*a(1)' | bc -l
3.1415926535897932384626433832795028841968
$
The function a
, loaded from the library by the -l
option, is for 'arctan'. I observe that at least 3 sources from a Google search 'pi 40 digits' suggests that it should be: 3.1415926535 8979323846 2643383279 5028841971 — which suggests that there's an error of 3 counts in the 40th digit from bc
.