unix shell:用字典替换

发布于 2024-11-15 22:36:42 字数 832 浏览 1 评论 0原文

我有一个包含一些数据的文件,像这样

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

,并且在单独的文件中有一些“字典”

100100 Event1
100200 Event2
100199 Event3
100235 Event4

,我知道

0 - warning
1 - error
2 - critical
etc...

我需要一些带有 sed/awk/grep 的脚本或其他可以帮助我接收这样的数据的脚本,我

100100 Event1 Error
100200 Event2 Warning
100199 Event3 Critical
etc

将不胜感激如何以最好的方式做到这一点,或者对于工作示例

更新

有时我有这样的数据

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

,其中sometext =任意6个字符(也许这是有用的信息)
在这种情况下我需要整个数据:

2011-01-02 sometext EventNameFromDictionary Error

或者没有“sometext”

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 some "dictionary" in separate file

100100 Event1
100200 Event2
100199 Event3
100235 Event4

and I know that

0 - warning
1 - error
2 - critical
etc...

I need some script with sed/awk/grep or something else which helps me receive data like this

100100 Event1 Error
100200 Event2 Warning
100199 Event3 Critical
etc

will be grateful for ideas how to do this in best way, or for working example

update

sometimes I have data like this

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

where sometext = any 6 characters (maybe this is helpful info)

in this case I need whole data:

2011-01-02 sometext EventNameFromDictionary Error

or without "sometext"

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

仲春光 2024-11-22 22:36:42
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
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
掩饰不了的爱 2024-11-22 22:36:42

为新要求添加新答案,并且由于注释中的格式选项有限:

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

如果您使用GNU awk,则无需转义三级运算符内的新行。

某些 awk 实现可能在这部分存在问题:

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

如果您使用其中之一,
修改为:

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

好的,评论补充:

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

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
佼人 2024-11-22 22:36:42

我希望 perl 也可以:

#!/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";
}

输出:

$ ./script.pl
2011-01-02      Event1  error
2011-01-02      Event2  warning
2011-01-02      Event3  3
2011-01-02      Event4  4

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文