I'm looking to turn this code into a for loop using awk with variable. It's a program that pulls the numbers under "totalframes", "landing lag", and "notes" for each of a character's aerial moves in Super Smash Bros. Example section of data:
<div >
<div >
Normal<a data-featherlight="hitboxes/fox/FoxFAir.gif"></a>
Landing<a data-featherlight="hitboxes/fox/FoxFAirLanding.gif"></a>
</div>
<div >
Forward Air
</div>
<div >
7/11/16/21/26
</div>
<div >
43
</div>
<div >
18
</div>
<div >
Landing hit on frame 1. Autocancels on frame 46 onward
</div>
<div >
1.8/1.2/1.72.7/4.8/2.0
</div>
<div >
4/4/4/5/12/9
</div>
<div >
2/2/2/2/3/3
</div>
<div >
Last one is landing hitbox
</div>
<div >
-14
</div>
<div >
7—8/11—12/16—17/21—22/26—27
</div>
</div>
<div >
<div >
<a data-featherlight="hitboxes/fox/FoxBAir.gif"></a>
</div>
<div >
Back Air
</div>
<div >
9
</div>
<div >
48
</div>
<div >
9
</div>
<div >
Autocancels on frame 1-6 and 18 onward
</div>
<div >
13.0
</div>
<div >
9
</div>
<div >
5
</div>
<div >
--
</div>
<div >
-4
</div>
<div >
9—11
</div>
</div>
<div >
<div >
<a data-featherlight="hitboxes/fox/FoxUAir.gif"></a>
</div>
<div >
Up Air
</div>
<div >
9/12
</div>
<div >
35
</div>
<div >
13
</div>
<div >
Autocancels on frame 1-8 and 25 onward
</div>
<div >
5.0/10.0
</div>
<div >
6/8
</div>
<div >
3/4
</div>
<div >
First/Second
</div>
<div >
-10/-9
</div>
<div >
9—10/12—13
</div>
</div>
Desired output:
Forward
43
18
46
Back
48
9
18
Up
35
13
25
Down
49
17
28
Neutral
38
7
32
Current solution:
echo -n "Character: "
read char
awk '/Forward Air$/{print $1; getline; getline; getline; getline; getline; getline; print $1; getline; getline; getline; print $1; getline; getline; getline; print $0}' data/chars/$char > output.txt
awk '/Back Air$/{print $1; getline; getline; getline; getline; getline; getline; print $1; getline; getline; getline; print $1; getline; getline; getline; print $0}' data/chars/$char >> output.txt
awk '/Up Air$/{print $1; getline; getline; getline; getline; getline; getline; print $1; getline; getline; getline; print $1; getline; getline; getline; print $0}' data/chars/$char >> output.txt
awk '/Down Air$/{print $1; getline; getline; getline; getline; getline; getline; print $1; getline; getline; getline; print $1; getline; getline; getline; print $0}' data/chars/$char >> output.txt
awk '/Neutral Air$/ {print $1; getline; getline; getline; getline; getline; getline; print $1; getline; getline; getline; print $1; getline; getline; getline; print $0}' data/chars/$char >> output.txt
grep -o -E ".{0,3}onward.{0,1}" output.txt > output2.txt
awk '{print $1}' output2.txt > output3.txt
The easiest way to simplify would seem to be to create a for loop, (e.g. "For ("Forward Air", "Back Air", "Up Air", "Down Air", "Neutral Air"), execute awk function"), but I haven't had any luck finding the correct syntax for this.
The getline spam is clunky, but I'm ignoring that for now because I learned that there are better tools than awk. I mainly just want to turn this into a for loop with awk using variable.
CodePudding user response:
You could use xsltproc
instead of awk
.
This piece of code gives you a first draft of what you try to achieve:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="utf-8"/>
<xsl:template match="/">
<xsl:for-each select="//div[@class = 'movecontainer']">
<xsl:value-of select="normalize-space(
div[@class = 'movename']/child::text())"/>
<xsl:text>
</xsl:text><!-- insert new line -->
<xsl:value-of select="normalize-space(
div[@class = 'totalframes']/child::text())"/>
<xsl:text>
</xsl:text><!-- insert new line -->
<xsl:value-of select="normalize-space(
div[@class = 'landinglag']/child::text())"/>
<xsl:text>
</xsl:text><!-- insert new line -->
<xsl:value-of select="normalize-space(
div[@class = 'notes']/child::text())"/>
<xsl:text>
</xsl:text><!-- insert new line -->
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Assuming the stylesheet above is called prog.xsl
and your input stays in a well formed XML file called input.xml
, you can launch xsltproc
as follows:
xsltproc prog.xsl input.xml
It will produce next output that still needs to be fine tuned:
Forward Air
43
18
Landing hit on frame 1. Autocancels on frame 46 onward
Back Air
48
9
Autocancels on frame 1-6 and 18 onward
Up Air
35
13
Autocancels on frame 1-8 and 25 onward
If this works for you, you have to add code for removing the string "Air" at the end of the movename
field, and for extracting the number you want from the note
field.
You could also filter this output through awk
or sed
for cleaning it according to your needs, as in:
xsltproc prog.xsl input.xml | sed -e '/ Air/s///' -e 's/^.* \([0-9]*\) onward$/\1/'
which gives you the output you want.
CodePudding user response:
This might be what you want with awk:
$ awk '
f { print $(/Autocancels/ ? NF-1 : 1); f=0 }
/<div >/ { f=1 }
' file
Forward
43
18
46
Back
48
9
18
Up
35
13
25