使用另一行中的值更新数据文件中的行

时间:2011-02-08 10:17:38

标签: perl parsing bash text-parsing

我有一些以制表符分隔的形式的数据,它提供来自用户代理(UA)的设备识别结果。但有几行设备被错误识别,我需要将它们更改为正确的。

例如,有些情况下,iphone或htc野火UA被识别为另一部手机。因此,对于这种情况,我需要通过在UA中搜索某些关键字来使用正确的设备更新设备信息。例如,

781 Mozilla/5.0 (Linux; U; Android 2.1-update1; fi-fi; HTC_Wildfire_A3333 Build/ERE27) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17  htc_wildfire_ver1_suba3333    HTC       Wildfire    Android

这是正确的,但类似的情况是错误的

775 Mozilla/5.0 (Linux; U; Android 2.1-update1; fi-fi; HTC Wildfire Build/ERE27) AppleWebKit/525.10+ (KHTML, like Gecko) Version/3.0.4 Mobile Safari/523.12.2 (AdMob-ANDROID-20100709)   T-Mobile       Pulse   Android

所以,我必须做这样的事情。我知道如果UA列包含术语HTC和Wildfire,那就是那部手机。所以,我想查找所有具有字符串HTC和Wildfire的UA,但是第3列和第4列(manufucturer和model)是错误的,然后使用第781行中的正确设备信息更新它们,我知道这是正确的。我会手动输入第781行是正确的代码,如果设备没有正确识别,我会把所有这些情况从第7行开始的第781行的信息。

当然这是一个案例,有几个这样的案例,我会为每个案例重复相同的逻辑。除了这四个之外还有其他专栏我没有展示过。

我将如何在perl脚本中完成此操作(最好,但bash解决方案也可以)。

1 个答案:

答案 0 :(得分:0)

  1. 通过循环输入文件创建具有所有不同(UA,制造商,型号)三元组的文件(设备),将三元组作为键存储在哈希中;将已排序的密钥写入设备
  2. 手动编辑设备(删除'错误'行)
  3. 将设备加载到哈希中,使用UA作为键,(制造商,型号)作为值。循环输入文件,使用当前行的UA字段查找设备,使用散列中的良好值更改这两个字段(如果需要)。

  4.     my @Log = (
            [ 'HTC', 'badModelHTC'  ]
          , [ 'ABC', 'badModelABC' ]
          , [ 'HTC', 'goodModelHTC' ]
          , [ 'ABC', 'badModelABC' ]
          , [ 'ABC', 'goodModelABC' ]
          , [ 'HTC', 'goodModelHTC' ]
          , [ 'ABC', 'badModelABC' ]
        );
        my %Devs;
        printf "----------- Log org\n";
        for (@Log) {
          printf "%s %s\n", @{$_};
          my $key = join '-', @{$_};
          $Devs{ $key } = $_->[ 1 ];
        }
        printf "----------- Devs org\n";
        for (sort( keys( %Devs ) )) {
          printf "%s => %s\n", $_, $Devs{ $_ };
          if (/bad/) {
              delete $Devs{ $_ };  # fake manual removal
          }
        }
        # fake manual shortening of keys
        my %Tmp = %Devs;
        %Devs = ();
        for (keys %Tmp) {
          $Devs{ (split( /-/, $_))[ 0 ] } = $Tmp{ $_ };
        }
        printf "----------- Devs corrected\n";
        for (sort( keys( %Devs ) )) {
          printf "%s => %s\n", $_, $Devs{ $_ };
        }
        printf "----------- Log corrected\n";
        for (@Log) {
          $_->[ 1 ] = $Devs{ $_->[ 0 ] };
          printf "%s %s\n", @{$_};
        }
    

    输出:

        ----------- Log org
        HTC badModelHTC
        ABC badModelABC
        HTC goodModelHTC
        ABC badModelABC
        ABC goodModelABC
        HTC goodModelHTC
        ABC badModelABC
        ----------- Devs org
        ABC-badModelABC => badModelABC
        ABC-goodModelABC => goodModelABC
        HTC-badModelHTC => badModelHTC
        HTC-goodModelHTC => goodModelHTC
        ----------- Devs corrected
        ABC => goodModelABC
        HTC => goodModelHTC
        ----------- Log corrected
        HTC goodModelHTC
        ABC goodModelABC
        HTC goodModelHTC
        ABC goodModelABC
        ABC goodModelABC
        HTC goodModelHTC
        ABC goodModelABC