【问题标题】:Sort a file based on key value pair at a different position in each line根据每行不同位置的键值对对文件进行排序
【发布时间】:2013-07-02 15:57:46
【问题描述】:

我有一个包含一堆键值对的文本文件。 每一行的键值对顺序不一样,只有我的序列键保证在每一行。

如何在 linux 中根据键值对文件进行排序? 例如

key1=blah key2=something key4=else sequence=3
sequence=1 key2=xlde key7=eldl
blahkey=xxx sequence=2 keyx=adada

我需要根据“序列”键对文件进行排序。即

sequence=1 key2=xlde key7=eldl
blahkey=xxx sequence=2 keyx=adada
key1=blah key2=something key4=else sequence=3

谢谢

【问题讨论】:

    标签: sorting keyvaluepair


    【解决方案1】:

    如果保证序列键不仅在每一行中,而且是唯一的并且其值不超过行数(如示例),您可以执行以下操作:

    1. 分配线条大小的数组。

    2. 对于每一行:

      2.1 检索文本中的序列号,方法是用 "sequence=" 和空格切片。

      2.2 将文本中的数字转为索引。

      2.3 将一行放入新数组的对应单元格中。

    在 Python 中是这样的:

    lines = [
    "key1=blah key2=something key4=else sequence=3",
    "sequence=1 key2=xlde key7=eldl",
    "blahkey=xxx sequence=2 keyx=adada"
    ]
    
    new_lines = [""] * len(lines)
    
    for line in lines:
        after_sequence = line.split("sequence=")[1]
        and_before_space = after_sequence.split(" ")[0]
        n = int(and_before_space) - 1
        new_lines[n] = line
    
    print new_lines
    

    【讨论】:

      【解决方案2】:

      如果我在 perl 中执行此操作,我会将整个文件吞入其中并对其进行处理,以便我可以根据原始原始行的序列号对其进行排序。我不确定您的文件格式有多一致,但一种 perl 方法可能是:

      #!/usr/bin/perl -w
      
      my @data;
      
      # slurp in each line, and tag it by its sequence number
      foreach my $line ( <STDIN> )
      {
          if ($line =~ /sequence=(\S+)/)
          {
              push @data, { sequence => $1, line => $line };
          } else
          {
              die "unhandled line: $line";  # only if needed
          }
      }
      
      # sort the lines by their sequence number into @sorted
      my @sorted = sort { $a->{sequence} <=> $b->{sequence} } @data;
      
      # generate the final result by extracting the original lines
      # from the sorted array and concatenating them
      my $result = join("", map { $_->{line} } @sorted);
      
      # output the sorted result
      print $result;
      

      我在你上面的例子中试过这个,它成功了。如果您可以在输入中包含脚本可以安全忽略的“垃圾”行,您可以按摩die 行。

      另外,如果你需要在升序和降序之间切换,你可以在这一行交换$a$b

      my @sorted = sort { $a->{sequence} <=> $b->{sequence} } @data;
      

      如果序列号不是纯数字,或者您想将它们作为字符串进行比较,请将&lt;=&gt; 运算符更改为cmp

      my @sorted = sort { $a->{sequence} cmp $b->{sequence} } @data;
      

      【讨论】:

      • 谢谢,删除了模具线,但对我有用。干杯!
      猜你喜欢
      • 2023-03-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-14
      • 2012-06-07
      • 1970-01-01
      • 2017-10-17
      相关资源
      最近更新 更多