1

I have this file.txt:

a b c
a f g
e h j

I wrote an awk script that does

BEGIN {...}
{...}
END {
    a = "a"
    b = "b"
    system("grep " a " file.txt | grep " b " > t")
}

I expect it to print a b c in file t. Running the same script from ConEmu on Windows 7 will produce an empty t file. On the other hand, executing grep a file.txt | grep b > t will produce the expected result.

why am I doing so: I'm parsing obscure data from a complicated file with multiple field separators (or nested fields, if you prefer). After having the structure of the input file (which is not file.txt), since each line is a command that will be executed and their order is important to me, I would like to know if something is set to something else and if that is a condition for a new command to be introduced in the input file using awk. The condition file database is file.txt.

Why is that? Am I doing something wrong? Am I blind somehow? On Windows 7, gawk 4.2.0, (GNU) grep 2.4.2

I'm also unable to locate similar questions that might help: if you know any, do flag this as duplicate.

Daemon Painter
  • 3,208
  • 3
  • 29
  • 44
  • 3
    Well, "works for me". :) (Using different tools of course.) You might want to consider an [MCVE](https://stackoverflow.com/help/mcve) to help express your problem in a more reproducible way. An *empty* file would be an indicator that your `system()` command ran, but the pipeline produced no output. Also .. this is purely academic, right? You're not *really* planning to write an awk script that runs `system("grep...")` like this, are you? A wider scope on this question that helps us understand a larger view of your problem would probably yield useful answers. – ghoti Feb 21 '18 at 13:45
  • Well, shame on me this is actually _not_ academic. I'm doing lots of stuff with awk, because I found it suitable to my needs for a lot of applications. Talking about this one: after having done stuff with my file, I'd like to see if `a` and `b` are present in a new, different file (aka a database, repository call it as you like). If they are present, then I would like to do more stuff. I do not believe that the problem lies in what happens in the remainder of the code. The only true difference is that `a` and `b` are inside arrays and passed as such to system. – Daemon Painter Feb 21 '18 at 13:48
  • 5
    Okay then, so if you want awk to find lines that contain both `a` and `b`, you might use `awk '/a/ && /b/' file.txt` ... or perhaps `awk -v a="a" -v b="b" '$0~a && $0~b' file.txt` if you want to load external variables. [No `system()` required](https://stackoverflow.com/q/19913446/1072112). Feel free to ask a bigger question; as it stands, this really feels like an [XY Problem](https://mywiki.wooledge.org/XyProblem). And if I can (1) figure out what you're trying to achieve or (2) replicate the problem you're having, I'll write up an answer. ;-) – ghoti Feb 21 '18 at 13:53
  • It might very well be an XY Problem of sort. I tend to develop tunnel vision when anxious. The topic on No system() required is really interesting. We are in that odd place of _in theory it works, but you really don't want to know why it doesn't_, right? – Daemon Painter Feb 21 '18 at 13:58
  • also, I've added a more detailed explanation on why am i doing so – Daemon Painter Feb 21 '18 at 14:16
  • 1
    It seems you didn't yet read the link in the first comment. To get useful answers, try to reduce your question to code which exhibits a [mcve]. – tripleee Feb 21 '18 at 14:54
  • @tripleee thanks for you input. I believe the code I'm providing is MCV. Indeed is Minimal, it is complete, letting you know I need a script (both because [I'm on windows](https://stackoverflow.com/a/4852413/2125110) and because I'm doing stuff in `BEGIN{}` and `{}`), the script works just fine until the relevant code I provided is executed. While, again, I agree that this might be an XY Problem (to a certain extent since I need to meet specs from my boss), I don't see why you should not be able to reproduce this code on a windows 7 VM yourself. I also posted an answer that solves my problem. – Daemon Painter Feb 22 '18 at 08:49
  • 1
    If the `BEGIN { ... } { ... }` parts are unnecessary to repro, then by definition it's not minimal. Example input and output are also necessary to make this verifiable. – tripleee Feb 22 '18 at 09:09
  • As I said, they are present to let you know stuff is done there, so I need an `awk` script and no, I'm not trying to have an `awk` script that launches an `awk` one-liner. And, before you ask, yes: there is at least one question on stack asking for that. No: I was not able to retrieve it with a quick search. Yes: I've seen it yesterday. Are you complaining because you have to literally delete 16 chars from a copy-paste process? Also: is that providing any additional detail about why it doesn't work, when it should? No salt intended Example input is there, as well as the output... – Daemon Painter Feb 22 '18 at 09:20
  • If you are worried that I've actually fixed the problem while making a MCVE, No: I've tested the MCVE and it doesn't work on my machine :( – Daemon Painter Feb 22 '18 at 09:21

1 Answers1

0

Since my goal was to achieve redirection of grep output to file from an awk script, and since the system() way did not work, I found this morning that:

BEGIN {...}
{...}
END {
    a = "a"
    b = "b"
    ask = "grep " a " file.txt | grep " b
    while (ask | getline _foo) {
        print _foo > "dump.txt"
    }
    close(ask)
}

works just fine. As a bonus, I can do stuff with each line returned by grep. Again, this is working in Windows 7 using gawk 4.2.0 and ConEmu.

Daemon Painter
  • 3,208
  • 3
  • 29
  • 44
  • 1
    That would spin off into an infinite loop on a getline failure and would produce cryptic error messages with some values of `a` and `b`. The syntax you're looking for is `ask = "grep \047" a "\047 file.txt | grep \047" b "\047"; while ( (ask | getline _foo) > 0 ) { ...`. See http://awk.freeshell.org/AllAboutGetline. There's almost certainly a better way to do whatever it is you're really trying to do that does not involve getline though. Save yourself a world of problems and install cygwin if you want to use UNIX tools from Windows. – Ed Morton Feb 25 '18 at 13:56
  • I will try to implement improvements into the code to avoid bad loops, thanks for your input! I'm still unsure about why system() wouldn't work - tbh it "works", it just prints flipping nothing in the file. – Daemon Painter Feb 26 '18 at 07:43
  • Beats me. Without a [mcve] there's really nothing we could do to help you debug that. – Ed Morton Feb 26 '18 at 11:54