bash - 按引用行对每对行进行排序

标签 bash shell sorting

我有以下名为 data 的文件(分隔符是空格,但为了清楚起见,这里我写了制表符):

a   b   c   d   e   f   g
a   c   d   f   e
21  18  32  31  35
b   a   f   e   d   g
12  22  21  28  32  33
...

从第二行开始,我希望通过将包含字母的行与文件的第一行匹配(a b c d e f g)来对每对行进行排序,并保留每对字母 -数,所以结果是:

a   b   c   d   e   f   g
a   b   c   d   e   f   g
21  0   18  32  35  31  0
a   b   c   d   e   f   g
22  12  0   32  28  21  33
...

请注意,对于每对行,可能会缺少字母,例如在 data 示例中,第一对行中缺少两个字母,第二对中缺少一个字母。这些字母在所需的输出中被分配为零。<​​/p>

到目前为止,我在网站上找到了以下代码:

while read line; do 
  sorted=$(sort -g -- <<< "${line// /$'\n'}")
  printf -- "${sorted//$'\n'/ }\n"
done < data

但它只是按字母或数字顺序对每一行进行排序:

a   b   c   d   e   f   g
a   c   d   e   f
18  21  31  32  35
a   b   d   e   f   g
12  21  22  28  32  33
...

有什么方法可以修改代码,使其通过匹配文件的第一行并保留每对行中的字母数字对来实现吗?

最佳答案

Perl 来救援:

perl -wle '@h = split " ", <>;
           print "@h";
           until (eof) {
               ($cols, $vals) = (scalar <>, scalar <>);
               my %map;
               @map{ split " ", $cols } = split " ", $vals;
               print "@h";
               print join " ", map $_ // 0, @map{@h};
           }' -- data
  • -l 处理输入和输出中的换行符
  • @h 是“标题”的数组,即从第一行获取的列名称。请参阅split .
  • %map 是一个哈希表,它将列映射到值。
  • @map{ list } 是哈希切片语法。它以相同的顺序返回列表中键对应的值。
  • // 运算符替换 undef (缺失值)为 0。

关于bash - 按引用行对每对行进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43544857/

相关文章:

linux - sudo 作为 www-data 文件权限

linux - 如何将附加字段附加到 CSV 文件中的每一行?

javascript - 如何在sublime上添加未定义数量的占位符的js片段

linux - Bash 颜色字符编码删除

bash - 变量在范围内的 for 循环将不起作用

用于简单自定义逻辑的java比较器

java - 使用 Java springdata 保存带有上限数组($slice 和 $sort)的 mongoDB 文档

c - 对动态数组 c 进行排序

linux - 根据修改日期删除子目录中的文件

linux - 如何创建配置脚本?