Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

One line external program output with getline

51 views
Skip to first unread message

Marc de Bourget

unread,
Jul 7, 2016, 4:19:37 AM7/7/16
to
I use getline to call external command line exe tools like mysql.exe or doff.exe on MS Windows. In my case the command line output of the external command line tool consists only of one line so a "getline" call with "if" is sufficient. The command line output is saved into an AWK variable for further use.

I have written two versions which both work as expected:

# Version 1:
BEGIN {
# Store DOS output (one line) from a program into an AWK variable:
cmd = "doff.exe yyyymmdd_hhmiss"
if ((cmd | getline awkvar) > 0) {
close(cmd)
}
print awkvar
}

# Version 2:
BEGIN {
# Store DOS output (one line) from a program into an AWK variable:
cmd = "doff.exe yyyymmdd_hhmiss"
if ((cmd | getline awkvar) > 0) {
print awkvar
}
close(cmd)
}

Is there something wrong with Version 1? It looks a bit fancier than Version 2 so I prefer this one, but will "cmd" always be correctly closed with Version 1?

I'm especially interested in Ed's answer, because he is "Mister Getline" :-)

Lorenz

unread,
Jul 7, 2016, 9:48:46 AM7/7/16
to
the manual says:
| The getline command returns one if it fnds a record and zero if it encounters the end
| of the fle. If there is some error in getting a record, such as a fle that cannot be opened,
| then getline returns -1.

Version 1 does not close the pipe in case the output of the command is
empty.

So you better test for < 0 to differenciate between the case that
getlines returns with an error and the command output is empty.
--

Lorenz

Janis Papanagnou

unread,
Jul 7, 2016, 10:08:50 AM7/7/16
to
On 07.07.2016 15:48, Lorenz wrote:
>> [...]
>
> the manual says:

I suppose "the manual" is the GNU awk manual that you quote?

> | The getline command returns one if it fnds a record and zero if it encounters the end
> | of the fle. If there is some error in getting a record, such as a fle that cannot be opened,
> | then getline returns -1.

$ awk 'BEGIN { if (("no-such-cmd" | getline d) >=0) print "triggered" }'
sh: 1: no-such-cmd: not found
triggered

$ awk --version
GNU Awk 4.1.2, API: 1.1 (GNU MPFR 3.1.0-p3, GNU MP 5.0.2)

Hmm...

Janis

Janis Papanagnou

unread,
Jul 7, 2016, 10:20:44 AM7/7/16
to
I'm wondering why you don't put both commands, print and close, into the
if-block.

And of course there are differences between the two versions; in case of a
cmd error the first version will print an empty line (or whatever content
the variable 'awkvar' had before).

Janis

Marc de Bourget

unread,
Jul 11, 2016, 6:33:07 AM7/11/16
to
Le jeudi 7 juillet 2016 16:20:44 UTC+2, Janis Papanagnou a écrit :
> I'm wondering why you don't put both commands, print and close, into the
> if-block.

Yes, this would be version 3:
# Version 3:
BEGIN {
# Store DOS output (one line) from a program into an AWK variable:
cmd = "doff.exe yyyymmdd_hhmiss"
if ((cmd | getline awkvar) > 0) {
print awkvar
close(cmd)
}
}

But of course version 2 is best:
# Version 2:
BEGIN {
# Store DOS output (one line) from a program into an AWK variable:
cmd = "doff.exe yyyymmdd_hhmiss"
if ((cmd | getline awkvar) > 0) {
print awkvar
}
close(cmd)
}

To complete this thread, if the output consists of several lines, something like the following snipppet (part of a script of mine) can be used:

# Several lines:
BEGIN {
# Store DOS output (several lines) from a program into an AWK variable:
pdf_path = "c:\\test\\"
cmd = "dir " pdf_path "*.pdf /A:-D/b"
while ((cmd | getline awkvar) > 0) {
print "#" awkvar "#"
}
close(cmd)
}
0 new messages