1

I want to override the child_value with the parent_value using awk. The solution must be generic applicable for larger data sources. The parent-record is defined by $1==$2.

This is my input file (format: ID;PARENT_ID;VALUE):

10;20;child_value
20;20;parent_value

This is the result I want:

10;20;parent_value
20;20;parent_value

This is my current approach:

  awk -F\;
        BEGIN {
            OFS = FS
        }
        {
            if ($1 == $2) {
                mapping[$1] = $3
            }
            all[$1]=$0
        } 
        END {
            for (i in all) {
              if (i[$3] == 'child_value') {
                 i[$3] = mapping[i]
              }
              print i
            }
        }
    ' file.in

Needless to say, that it doesn't work like that ;-) Anyone can help?

4
  • 1
    Is child_value is constant or dynamic value ? Will it have more than one child-parent values ? If so, How to match parent and corresponding child ? Commented Mar 23, 2017 at 14:24
  • Can a child have a child (ie. 5;10;typical_teen_value)? Does it get parent_value or child_value? Commented Mar 23, 2017 at 15:30
  • @JamesBrown there is no recursion Commented Mar 26, 2017 at 7:13
  • @sat actually child_value will be constantly an empty string Commented Mar 26, 2017 at 7:13

2 Answers 2

1

for multiple parent/child pairs perhaps on non-consecutive lines...

$ awk -F\; -v OFS=\; 'NR==FNR {if($1==$2) a[$2]=$3; next} 
                      $1!=$2  {$3=a[$2]}1' file{,}

10;20;parent_value
20;20;parent_value

assumes the second field is the parent id.

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

1 Comment

This solutions works perfectly. Many thanks @karakfa!
0

Well, if your data is sorted in descnding order (you could use sort if not sorted at all or rev if data is sorted in ascending order) before processing, it's enough to hash the first entry of each key in $2 and use the value on the first match for the following records with the same key in $2:

$ sort -t\; -k2nr -k1nr bar | \ 
awk '
BEGIN{ 
    FS=OFS=";"
}
{
    if($2 in a)      # if $2 in hash a, use it
        $3=a[$2]     
    else             # else add it
        a[$2]=$3
    if(p!=$2)        # delete previous entries from wasting memory
        delete a[p]
    p=$2             # p is for previous on next round
}1'
20;20;parent_value
10;20;parent_value

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.