unix shell: replace by dictionary

后端 未结 3 642
走了就别回头了
走了就别回头了 2020-12-15 14:59

I have file which contains some data, like this

2011-01-02 100100 1 
2011-01-02 100200 0
2011-01-02 100199 3
2011-01-02 100235 4

and have s

相关标签:
3条回答
  • 2020-12-15 15:37

    Adding a new answer for the new requirement and because of the limited formatting options inside a comment:

    awk 'BEGIN {
     lvl[0] = "warning"
     lvl[1] = "error"
     lvl[2] = "critical"
     }
    NR == FNR {
      evt[$1] = $2; next
      } 
    {
      if (NF > 3) {
        idx = 3; $1 = $1 OFS $2
        }
      else idx = 2  
      print $1, $idx in evt ? \
        evt[$idx] : $idx, $++idx in lvl ? \
          lvl[$idx] : $idx
      }' dictionary infile
    

    You won't need to escape the new lines inside the tertiary operator if you're using GNU awk.

    Some awk implementations may have problems with this part:

    $++idx in lvl ? lvl[$idx] : $idx
    

    If you're using one of those, change it to:

    $(idx + 1) in lvl ? lvl[$(idx + 1)] : $(idx + 1)
    

    OK, comments added:

    awk 'BEGIN {
     lvl[0] = "warning"       # map the error levels
     lvl[1] = "error"                
     lvl[2] = "critical"      
     }                        
    NR == FNR {               # while reading the first
                              # non-empty input file
      evt[$1] = $2          # build the associative array evt
      next                    # skip the rest of the program
                              # keyed by the value of the first column
                              # the second column represents the values
      }                       
    {                         # now reading the rest of the input
      if (NF > 3) {           # if the number of columns is greater than 3
        idx = 3               # set idx to 3 (the key in evt)
        $1 = $1 OFS $2       # and merge $1 and $2
        }                     
      else idx = 2            # else set idx to 2
      print $1, \              # print the value of the first column
        $idx in evt ? \    # if the value of the second (or the third,
                      \       # depeneding on the value of idx), is an existing
                      \       # key in the evt array, print its value
        evt[$idx] : $idx, \ # otherwise print the actual column value
        $++idx in lvl ?   \   # the same here, but first increment the idx 
         lvl[$idx] : $idx       # because we're searching the lvl array now     
      }' dictionary infile
    
    0 讨论(0)
  • 2020-12-15 15:39

    I hope perl is ok too:

    #!/usr/bin/perl
    use strict;
    use warnings;
    
    open(DICT, 'dict.txt') or die;
    my %dict = %{{ map { my ($id, $name) = split; $id => $name } (<DICT>) }};
    close(DICT);
    
    my %level = ( 0 => "warning", 
                  1 => "error",
                  2 => "critical" );
    
    open(EVTS, 'events.txt') or die;
    
    while (<EVTS>)
    {
        my ($d, $i, $l) = split;
        $i = $dict{$i}  || $i;  # lookup
        $l = $level{$l} || $l;  # lookup 
        print "$d\t$i\t$l\n";
    }
    

    Output:

    $ ./script.pl
    2011-01-02      Event1  error
    2011-01-02      Event2  warning
    2011-01-02      Event3  3
    2011-01-02      Event4  4
    
    0 讨论(0)
  • 2020-12-15 15:54
    awk 'BEGIN {
     lvl[0] = "warning"
     lvl[1] = "error"
     lvl[2] = "critical"
     }
    NR == FNR {
      evt[$1] = $2; next
      } 
    {
      print $2, evt[$2], lvl[$3]
      }' dictionary infile
    
    0 讨论(0)
提交回复
热议问题