? How to make AWK do *something* without giving it any stdin nor inputfile? Can it be done?
QUESTION 1:
Take for example this code: Code:
df | awk '{print $1}' Doesn't seem to be that simple. Here's some examples: Code:
# Works for some reason, and I think only in Bash (nothing is required in the $() :) Code:
# Works, but has a useless echo and pipe: Code:
# Works but requires a keypress before it will run, and outputs that keypress: Code:
# still require input & ENTER key, and prints that input with output; also it prints whole input record, not $1: Code:
# works great (again probably only Bash).. (wondering how this differs from a pipe into stdin?): This is more a curiosity than anything - I don't mind reading, so if it's not a simple "yes/no" and there's something to read on this, a link or two is just peachy! :) Thanks. |
Hi,
did you check awk man page? ----- quote from awk man page ---------- gawk [ POSIX or GNU style options ] -f program-file [ -- ] file ----- end of quote --------------------- As you can see, awk will work on files. There is no need for any kind of standard input to get awk work. |
mesiol, thanks.
I'm familiar with the man page, yes :) but have not (yet) found a way to make the -f <program-file> thing, and/or -- file thing, apply to this situation. That still requires an input file or program file. I don't want any files involved. Maybe I didn't make my OP clear enough. I don't want to give anything on stdin, AND I don't want to give any external files. :) Am I missing something? |
In order to spare you the ENTER key :
awk 'BEGIN { while ((getline line < system("df") > 0)) { print $1 }; exit}' The merit is still yours for the code, I have just added the BEGIN keyword :) |
J has given the solution but thought I would just throw an alternative to think about as well :)
Code:
awk 'BEGIN{while("df" |& getline)print $1}' |
Code:
awk 'BEGIN{ while( ("df"|getline) >0 ){ print $1} }' |
The "df" command string is put in a hash so that when it's first opened, a new fd is presented to it,.. so it's not really opened more than once in a loop unless you cast close().
More specifically with something that's similar to C styles it can be like this: Code:
awk ' |
Thanks to J_Szucs (post #4) for the idea to add BEGIN, that solved the problem of requiring input to make the program start. But my not-so-merit-worthy code in that post, printed the entire input record out in one shot, seemingly when it was all read in (and I suppose, when the file descriptor got closed), so my using $1 in that code didn't work -- maybe this is what ghostdog74 was saying in post #6?:
Code:
when you do a getline by itself, its still $0 Posts #5 and #6 (ghostdog + grail) both illustrate exactly what I was trying to figure out; I dunno how I managed to overlook the relative simplicity of the commands during my experimentation! Only difference between post #5 and #6 is post #5 uses the "co-process" pipe instead of the usual pipe. The man page says the |& coprocess symbol is not valid in --posix mode, let's see: Code:
sasha@reactor: awk --posix 'BEGIN{ while ("df"|&getline){ print $2} }' QUESTION: what is the real difference(s) between | and |& in this command? (You don't have to answer, I'll look it up!) konsolebox: your post shows an example of how/when the close() statement is used; I had been wondering why there is a close() but there is no open() command. But I still wonder, does it *need* to be used, particularly in the context of this thread? What if it's not used? Any difference anywhere, as far as memory use or anything? And, I don't understand the bit about 'hashes' -- neither in this context, or perhaps any other context. I slept in on the day they taught us about hashes. :D My next post will demonstrate what I'm getting at with all this. Thanks for everyone's input thus far. |
Quote:
Code:
while ( .. | getline ) From there, you can call your fields like normal. $1,$2 .... |
Ahh, yes thanks, I understand. As opposed to this:
Code:
awk --posix 'BEGIN{ while ("df"|getline line){ split(line,parts); print parts[2]} }' And.. My next post will not yet demonstrate where I'm going with this. |
testing: "df | awk" in the shell, vs awk -f "(df | getline)"
So despite that this code is working on the commandline, it doesn't work as a script. I take that back - it *does* work as a script, but to do it in a loop, I need to close() the fd after each run, otherwise, I suppose what happens if the thing runs once, the fd remains open but there's no more data, and the program just sits there. Or, it just runs once and exits. This works anyhow: Code:
#!/usr/bin/awk -f Code:
#!/bin/bash Code:
#!/bin/dash Code:
#!/bin/dash Code:
#!/usr/bin/awk -f Well, the reason for this thread was "why didn't the command line of awk work, with no stdin nor files", and that has been solved thanks to those contributors above. :) Thanks for this! Even though I'll mark it solved, further input on anything in here will be welcome. |
Quote:
Code:
for ((var=0; var<=10000; var++)); do It may also pay to look at flushing after you close / don't close as well to see if that helps Code:
fflush("df") |
Well, maybe I'm just having a really off sort of day.. Actually I don't feel great, maybe getting a cold, so if I'm missing dumb obvious things today, that's my excuse. :)
As for "does dash support that loop?", well as far as I knew until right now, it did. I've written most of my scripts to run in any shell, and I'd be 100% surprised if I don't have a single working loop in some of my scripts. But, I just created a simple dash script with a loop and an echo statement, and it failed to run the same way: Code:
sasha@reactor: ./dash_loop I'm baffled. Here's the manpage for dash: Quote:
I'll check what the usage of fflush() does in my test programs above and update again in a bit. |
Haven't checked fflush() effects yet, but here's the simple workaround for lack of a for loop, using `seq` instead:
Code:
#!/bin/dash |
@GrapefruiTgirl, @grail I think by default awk closes all file descriptors that are still open when it exits. It's just a way of demonstrating how opening and closing of command pipes works in awk.
@GrapefruiTgirl I sometimes call associative arrays as hashes or vice versa. So with internal hashes in awk, any command string can be associated with a single value.. a single fd that is. Here's an example awk script that necessarily requires close(): http://www.linuxquestions.org/questi...0/#post4066219 |
All times are GMT -5. The time now is 12:27 AM. |