0

I have to parse a file, kind of a config file, that is adopting a really simple grammar : there are 2 kind of multiline blocks and inline markup tags .

the block of type 1 is marked by an open_tag and a closing_tag plus the name of the block, example

START_BLOCK_1 name
   < content >
END_BLOCK_1

blocks of type 1 only contain blocks of type 2, they are basically used to switch on or off blocks of this configuration file .

the block of type 2 is marked by a tag at the start of a new line ( plus the name ) and there is non closing tag, the closing is implicitly made when a new block starts or when the file ends, the block itself is allowed to contain empty lines .

START_BLOCK_2 name_1
    < content >
    < content >
    < content >

START_BLOCK_2 name_2

    < content >

    < content >
    < content >

START_BLOCK_2 name_3
    < content >
    < content >

the final kind of token is just an inline tag, a special word that is present at the start of the line and I just to get what is the value marked by that tag

START_BLOCK_2 name_1

    tag_1 red

    tag_2 Jon

START_BLOCK_2 name_2
    tag_1 blue
    tag_2 Phil

A good final example could be

START_BLOCK_2 name_1
    < content >

START_BLOCK_2 name_2

    < content >

START_BLOCK_1 name_1
    START_BLOCK_2 name_3
        < content >

    START_BLOCK_2 name_4

        < content >

END_BLOCK_1

START_BLOCK_2 name_5
    < content >

Considering the names of blocks of type 2 I need to know the values associated to each tag ( if they contain tags that are set ) and if they are part of type 1 blocks and in this case the name attribute of the type 1 block that contains them .

The result could be stored in a file or printed out, as long as I can parse this I can always re-read the output later in a formatted way .

It's relatively simple to parse this file but I have never done such thing with just a GNU/linux shell and I would like to know if this is possible and the names of the tools made for this .

EDIT

input

START_BLOCK_2 opt1
color red

START_BLOCK_1 opt2
    START_BLOCK_2 opt3
        name Jon

    START_BLOCK_2 opt4

        color blu

END_BLOCK_1

expected output

opt1 red

opt3 opt2
opt3 Jon

opt4 opt2
opt4 blu
  • While you could probably make something work with, say, awk, in general parsing problems do better with real parsers, and so I'd usually write one in another language like python or perl – Eric Renouf Nov 18 '16 at 18:06
  • @EricRenouf the only reason why I'm still not using a scripting language is because, in theory, this file can still be read line by line ( like many GNU utility do ) and be interpreted correctly . – user31223 Nov 18 '16 at 18:08
  • OM what way do you want to "know" the tags/values and so forth. Do you want them in shell variables, printed in some format etc? What would "success" look like here. And as I noted, you could probably make awk do this, or you could even do it in the shell directly with a while loop. – Eric Renouf Nov 18 '16 at 18:11
  • @EricRenouf I have added an example – user31223 Nov 18 '16 at 18:21
2

Here's an awk solution, assuming you don't want the blank lines in your example output.

awk '/START_BLOCK_1/ { block1=$2; next; } \
/END_BLOCK_1/ {block1=""; next; } \
/START_BLOCK_2/ { block2=$2; next; } \
/./ { if(block1) {print block2 " " block1} if(block2) { print block2 " " $2}
}' inp

it works by matching each line for a start or end block. If we are "in" a BLOCK_1 we'll have the name set in the block1 variable. If we're "in" a BLOCK_2 we'll have that name set in the block2 variable. Any line that doesn't define a block and isn't empty (matches at least 1 character) we'll then print out stuff based on the blocks we're in.

  • I think that I still have to tweak it a bit, just because sometimes type 2 blocks can be marked by different tokens but I think we are more or less there . One question : what is the technical or specific name for the /./ portion and similar ? – user31223 Nov 18 '16 at 18:53
  • @user31223 the / symbols denote that what is between them is a regular expression. As a regex . matches any single character – Eric Renouf Nov 18 '16 at 23:56
  • What I meant was the technical name for it, I noticed that awk is calling them patterns which I think is the name for the thing – user31223 Nov 19 '16 at 18:48
  • @user31223 if you look at the POSIX definition for awk you'll see that the general form for the awk program is pattern { action } and the section on patterns shows that regular expressions are one form of accepted patterns, but there are others like the special BEGIN and END patterns, or other types of expression (like, say, $1 == "first") or a range – Eric Renouf Nov 19 '16 at 19:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.