Home > database >  Nesting awk with variable in for loop?
Nesting awk with variable in for loop?

Time:03-19

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>&#xa;</xsl:text><!-- insert new line -->
      <xsl:value-of select="normalize-space(
        div[@class = 'totalframes']/child::text())"/>
      <xsl:text>&#xa;</xsl:text><!-- insert new line -->
      <xsl:value-of select="normalize-space(
        div[@class = 'landinglag']/child::text())"/>
      <xsl:text>&#xa;</xsl:text><!-- insert new line -->
      <xsl:value-of select="normalize-space(
        div[@class = 'notes']/child::text())"/>
      <xsl:text>&#xa;</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
  • Related