Combine awk commands into one

my code:

gawk 'NR>'"${LASTLINENUM}"' && NR<='"${LINEENDNUM}"'' ${LOGFILE} | gawk '{l[NR]=$0;} /'"${STRING1}"'/ && /'"${STRING2}"'/ {for (i=NR-'"${BEFOREGLAF}"'; i<=NR+'"${AFTERGLAF}"'; i++) o=i; t++;} END { for(i=1; i<=NR; i++) if (o) print l; print t+=0;}'

i would like to combine this into one and have it operate exactly as the original code above.

i tried the following and it didn't work:

gawk '{NR>'"${LASTLINENUM}"' && NR<='"${LINEENDNUM}"' && l[NR]=$0;} /'"${STRING1}"'/ && /'"${STRING2}"'/ {for (i=NR-'"${BEFOREGLAF}"'; i<=NR+'"${AFTERGLAF}"'; i++) o=i; t++;} END { for(i=1; i<=NR; i++) if (o) print l; print t+=0;}'

I refuse to attempt to do 1-liners where I can't see what it is doing. And, with no sample variable values and no sample data to work on and no description of the expected output, this is obviously totally untested, but should come close to what your unreadable pipeline did:

gawk -v ll="$LASTLINENUM" -v le="$LINEENDNUM" -v s1="$STRING1" \
     -v s2="$STRING2" -v bg="$BEFOREGLAF" -v ag="$AFTERGLAF" '
NR <= ll || NR > le {
	ndel++
	next
}
{	l[NR - ndel] = $0
}
$0 ~ s1 && $0 ~ s2 {
	for(i = NR - ndel - bg; i <= NR - ndel + ag; i++)
		o = i
	t++
}
END {	for(i = 1; i <= NR - ndel; i++)
		if(o)
			print l
	print t+0
}' "$LOGFILE"

I think that the expression NR - ndel keeps track of the NR value that would have been seen in the second awk script. Without understanding what the shell variables BEFOREGLAF and AFTERGLAF are doing in your script, I have no idea whether or not any of the ndel calculations are needed as is, could be simplified by changing those two shell variables, or could just be skipped entirely.

2 Likes

Without being able to understand WHAT you are doing in your above two awk commands, try

awk -vLLN="$LASTLINENUM" -vLEN=$LINEENDNUM" '
NR <= LLN       {next
                }
NR >  LEN       {exit
                }
... your second script's contents ...

' ${LOGFILE}
1 Like

the command searches for a pattern, and grabs a specific number of lines that come before AND after the pattern is found.

There are solutions around in here, e.g. using a "ring buffer", that do this more understandably (and mayhap elegantly).

1 Like

As a general remark about one-liners: one-liners reduce readability and understandability. Their advantage is that they can be fastly written.

Given that you are unable to modify your already existing one-liners (which i take as a hint that you are not completely understanding them already) i suggest that it is a bad idea to combine these to an even more complex construct which you are bound to understand even less.

It is of course always possible to rely on us (or other people like us) to provide modifications as the code will need to be modified but, honestly: do you really want to preside over an environment where you do not understand what is going on? It might be me but i for my part would have a very bad feeling being in such a position.

It is in your own best interest if you rely on us only if you need an explanation to further your understanding but not to write or modify your productive code. Whatever you use finally you should be able to produce on your own and you should write it in a way that you are able to understand its inner workings.

Btw., over time i found that restricting my written code to 80 characters per line with only select few exceptions (for instance definitions of string constants) makes my code more readable and better overall. The reason is that a line containing more than 80 characters is most likely badly formed and should be rewritten in a more conclusive manner anyways. This in most cases means i reformat one-liners to their long form.

Here is an example where i filter out comments and whitespace from an input file before processing:

sed 's/#.*//;s/^[ 	]*//;s/[ 	]*$//;/^$/d' "$fCmd" | while read chCmd ; do
     .....
done

Going over that code i modified it to:

sed 's/#.*//
     s/^[ 	]*//
     s/[ 	]*$//
     /^$/d' "$fCmd" |\
while read chCmd ; do
     .....
done

I'd say the second variant gives you a much cleaner and easier to grasp impression of what is going on than the first.

I hope this helps.

bakunin

1 Like