Shell/Bash parsing text file

19,400

Solution 1

If you want to continue down the shell road, you can do something like this:

item_re="^(Item.*):$"
while read -r; do
    if [[ $REPLY =~ $item_re ]]; then
        item=${BASH_REMATCH[1]}
    else
        printf "%s=>%s\n" "$item" "$REPLY"
    fi
done < file.txt

Solution 2

Text parsing is best done with awk:

$ awk '/:$/{sub(/:$/,"");h=$0;next}{print h"=>"$0}' file
Item=>SubItem01
Item=>SubItem02
Item=>SubItem03
Item2=>SubItem0201
Item2=>SubItem0202
Item3=>SubItem0301

Solution 3

Using awk

awk '/:/{s=$1;next}{print s OFS $0}' FS=: OFS="=>" file

Solution 4

Here's another awk alternative:

awk -F: '/^Item/{ITM=$1} !/^Item/{print ITM"=>"$0}'

If a line begins with 'Item', save the item name in ITM. If the line does not begin with 'Item', print the previously saved item name (ITM), '=>', and the sub item. Splitting on : makes it easier to get the item name.

The assumption is that groups of subitems will always be preceded by an Item: entry, so the variable ITM should always have the name of the current group.

Solution 5

TXR Solution:

@(collect)
@left:
@  (collect)
@right
@  (until)
@(skip):
@  (end)
@(end)
@(output)
@  (repeat)
@    (repeat)
@left=>@right
@    (end)
@  (end)
@(end)

$ txr regroup.txr data.txt
Item=>SubItem01
Item=>SubItem02
Item=>SubItem03
Item2=>SubItem0201
Item2=>SubItem0202
Item3=>SubItem0301
Share:
19,400
FanaticD
Author by

FanaticD

Updated on June 04, 2022

Comments

  • FanaticD
    FanaticD almost 2 years

    I have this text file, which looks like this

    Item:
    SubItem01
    SubItem02
    SubItem03
    Item2:
    SubItem0201
    SubItem0202
    Item3:
    SubItem0301
    ...etc...
    

    And I need is to get it to look like this:

    Item=>SubItem01
    Item=>SubItem02
    Item=>SubItem03
    Item2=>SubItem0201
    Item2=>SubItem0202
    Item3=>SubItem0301
    

    I am aware of the fact, that I need two for loops to get this. I did some tests, but... well, it didn't end up well.

    for(( c=1; c<=lineCount; c++ ))
    do
    
       var=`sed -n "${c}p" TMPFILE`
       echo "$var"
    
       if [[ "$var" == *:* ]];
       then
       printf "%s->" $var
       else
       printf "%s\n"
       fi
    done
    

    Could anyone please kick me back on the road? I tried bunch of variete ways, but I am not getting anywhere. Thanks.

  • FanaticD
    FanaticD about 10 years
    Thank you, this is probably exactly what I was looking for!
  • FanaticD
    FanaticD about 10 years
    Thank you, I appreciate your help!
  • FanaticD
    FanaticD about 10 years
    Be sure I would do that... if my reputation was high enough.
  • bjb568
    bjb568 about 10 years
    Could you provide an explanation? Currently your answer is incomplete.
  • Cole Tierney
    Cole Tierney about 10 years
    @bjb568 I've added an explanation. Does that help?