 <p>Here's one way using <code>GNU awk</code>. Run like:</p> <pre><code>awk -f script.awk file1 file2 </code></pre> <p>Contents of <code>script.awk</code>:</p> <pre><code>BEGIN { FS="[ =:,]" } FNR==NR { a[$1]=$0 next } $2 in a { split(a[$2],b) for (i=3;i&lt;=NF-1;i+=2) { for (j=2;j&lt;=length(b)-1;j+=2) { if ($(i+1) == b[j]) { line = (line ? line "," : "") $i ":" b[j+1] } } } print $1 "=" line line = "" } </code></pre> <p>Results:</p> <pre><code>Tom=John:5,Mike:5 </code></pre> <p>Alternatively, here's the one-liner:</p> <pre><code>awk -F "[ =:,]" 'FNR==NR { a[$1]=$0; next } $2 in a { split(a[$2],b); for (i=3;i&lt;=NF-1;i+=2) for (j=2;j&lt;=length(b)-1;j+=2) if ($(i+1) == b[j]) line = (line ? line "," : "") $i ":" b[j+1]; print $1 "=" line; line = "" }' file1 file2 </code></pre> <p>Explanation:</p> <blockquote> <p>Change awk's field separator to a either a space, equals, colon or comma.</p> <p>'FNR==NR { ... }' is only true for the first file in the arguments list.</p> <p>So when processing file1, awk will add column '1' to an array and we assign the whole line as a value to this array element.</p> <p>'next' will simply skip processing the rest of the script, and read the next line of input.</p> <p>When awk has finished reading the input in file1, it will continue reading file2. However, this also resets 'FNR' to '1', so awk will skip processing the 'FNR==NR' block for file2 because it is not longer true.</p> <p>So for file2: if column '2' can be found in the array mentioned above:</p> <blockquote> <p>Split the value of the array element into another array. This essentially splits up the whole line in file1.</p> <p>Now create two loops.</p> <blockquote> <p>The first will loop through all the names in file2</p> <p>And the second will loop through all the values in the (second) array (this essentially loops over all the fields in file1).</p> </blockquote> <p>Now when a value succeeding a name in file2 is equal to one of the key numbers in file1, create a line construct that looks like: 'name:number_following_key_number_from_file1'.</p> <p>When more names and values are found during the loops, the quaternary construct '( ... ? ... : ...)' adds these elements onto the end of the line. It's like an if statement; if there's already a line, add a comma onto the end of it, else don't do anything.</p> <p>When all the loops are complete, print out column '1' and the line. Then empty the line variable so that it can be used again.</p> </blockquote> </blockquote> <p>HTH. Goodluck.</p>