1

I am working through a really complex and long multi-conditional statement to do this and was wondering if anyone knew of a simpler method. I have a multi-column/multi-row list that I am trying to parse. What I need to do is take the first row which has the "*" in the 5th position and copy all those entries into the blank spaces on the next few rows and then discard the original top row. What complicates this a bit is that sometimes the next few rows may not have an empty space in all the other fields (see bottom half of original list). If that's the case, I want to take extra entry (Q1 below) and put it at the end of row, in a new column.

Original list:

A B C D ***** F G
    E1
    E2
    E3
Q R S T ***** V W
    U1
Q1  U2

Final output:

A B C D E1 F G
A B C D E2 F G
A B C D E3 F G
Q R S T U1 V W
Q R S T U2 V W Q1

Thanks in advance for help!

4
  • Awk is a good way to do this, show what you've tried and someone should help you fix it. Commented Apr 22, 2013 at 19:32
  • @Barmar No I definitely don't want anyone else to write it for me. If someone could just point me in the right direction. Right now I'm using for i in $myoutput| awk '{print $5}' to go row by row and check to see if the fifth field is all ********* at which point I start a new row with new field names from $1,2,3,4,6,7. Commented Apr 22, 2013 at 19:44
  • 2
    You should be doing the whole thing in awk, as in sudo_O's answer. Commented Apr 22, 2013 at 19:46
  • could your E1 E2 E3 rows have more columns, but not from the beginning of line? Commented Apr 22, 2013 at 19:52

1 Answer 1

1

The concise/cryptic one liner:

awk '/[*]/{f=$0;p="[*]+";next}{r=$2?$2:$1;sub(p,r,f);p=r;print $2?f" "$1:f}' file
A B C D E1 F G
A B C D E2 F G
A B C D E3 F G
Q R S T U1 V W
Q R S T U2 V W Q1

Explanation:

/[*]+/ {                  # If line matches line with pattern to replace
    line = $0             # Store line
    pat="[*]+"            # Store pattern
    next                  # Skip to next line
}
{
    if (NF==2)            # If the current line has 2 fields 
       replace = $2       # We want to replace with the second
    else                  # Else
       replace = $1       # We want to replace with first first

    sub(pat,replace,line) # Do the substitution
    pat=replace           # Next time the pattern to replace will have changed 

    if (NF==2)            # If the current line has 2 fields
       print line,$1      # Print the line with the replacement and the 1st field
    else                  # Else
       print line         # Just print the line with the replacement 
}

To run the script save it to a file such as script.awk and run awk -f script.awk file.

Sign up to request clarification or add additional context in comments.

3 Comments

That's perfect! Thank you! But I am still learning awk and may I ask you for some clarification? I understand what {r=$2?$2:$1;sub(p,r,f);p=r;print $2?f" "$1:f}' does, but what does the logic do here here: /[*]/{f=$0;p="[*]+";next} @sudo_O
Next question: Where can I send the fruit basket? ;-) Thank you!
Haha my pleasure :) best way to show thanks it just to upvote.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.