The UNIX and Linux Forums  


Go Back   The UNIX and Linux Forums > Top Forums > Shell Programming and Scripting
.
google unix.com




View Single Post in the UNIX and Linux Forums - Click on the Thread or Permalink to View Entire Thread -->
  #4 (permalink)  
Old 06-09-2008
radoulov's Avatar
radoulov radoulov is offline Forum Staff  
addict
  
 

Join Date: Jan 2007
Location: Варна, България / Milano, Italia
Posts: 2,915
Quote:
Originally Posted by mecano View Post
[...]
if I understand correctly, awk reads the two files and automagically merged records itself ? It means that there is no need to store values from file1 to compare them to file2 ? Beautifull...
[...]
It uses an associative array (a hash), so it guarantees the uniqueness
of the key ($NF in this case) and the value is alway the last one it sees
(the one in file2). It will associate to every key ($NF) the entire record ($0) and it will update the value when it sees the same key.

Quote:
Two things I don't get: the use of the underscore (while i guess it stands for "all read records" ?), and why is END not at the end ?
Well, this is kinda style of writing,
it you want the code more readable,
you could use this instead (and this is compatible even with the old plain Solaris awk):


Code:
awk '{
  key_record[$NF] = $0     # associate key ($NF) with entire record ($0) 
  }
END { 
  # after the entire input has been read 
  for (key  in key_record) # for every key stored
    print key_record[key]  # print the associated value
    }' file1 file2

Quote:
About the sort command wouldn't it fail on the ';' ?
I think the sort command will cast it correctly. Do you have an example where the input like this is not sorted correctly?

Quote:
Do you know how to specify 'last field' of line with sort ?
Or is something like :
| awk '{ printf substr($NF, 1, length($NF)-1);$NF = "";printf " %s\n",$0 }' | sort -n | awk '{ printf "%s%s;\n",$0,$1 }' | awk '{$1="";sub(/^ +/, "");printf "%s\n",$0}'
preferable ?
Why? Isn't the last field position fixed?
In that case I would go with:


Code:
perl -lane'
  $h{$F[-1]} = $_;
  print join "\n", map $h{$_}, sort {$a <=> $b} keys %h 
    if eof'

Or (if you really want to get rid of the ';' while sorting):


Code:
perl -lane'
  chop $F[-1] and $h{$F[-1]} = $_;
  print join "\n", map $h{$_}, sort {$a <=> $b} keys %h 
    if eof'

Otherwise using sort + shell:


Code:
read<file;set -- $REPLY;sort -k$#n file