如何使用Sed或Perl根据字符串的第二列号以降序方式对给定的文本文件进行排序

时间:2019-05-19 23:49:13

标签: perl sed

如何使用Sed或Perl根据字符串的第二列号以降序对给定的文本文件进行排序

Input.txt

123|N1-G23-H40-K1-A11-C12-J12|banana|boy      
123|Z12|Goal|test     
123|F1-B23-G39-M22-Z12|some|girl     
123|E1-T23-N12|car|girl     
123|N1-G23-H40-K1-A11-C12|banana|boy     
123|V1-M12|car|girl     
123|P1-G23-H40-K1|school|boy

Output.txt

123|N1-G23-H40-K1-A11-C12-J12|banana|boy   
123|N1-G23-H40-K1-A11-C12|banana|boy    
123|F1-B23-G39-M22-Z12|some|girl    
123|P1-G23-H40-K1|school|boy    
123|E1-T23-N12|car|girl    
123|V1-M12|car|girl     
123|Z12|Goal|test

2 个答案:

答案 0 :(得分:0)

使用Schwartzian Transform中的Perl,请尝试以下操作:

perl -e '
    print map { $_->[0] }
    sort { $b->[1] <=> $a->[1] }
    map { [$_, length((split(/\|/))[1])] }
    <>;
' input.txt

输出:

123|N1-G23-H40-K1-A11-C12-J12|banana|boy
123|N1-G23-H40-K1-A11-C12|banana|boy
123|F1-B23-G39-M22-Z12|some|girl
123|P1-G23-H40-K1|school|boy
123|E1-T23-N12|car|girl
123|V1-M12|car|girl
123|Z12|Goal|test

[工作原理]

要了解算法,阅读脚本会很方便 从底部到顶部。

第一个功能:

map { [$_, length((split(/\|/))[1])] }
<>;

读取输入文件,然后生成保存输入行的二维列表 本身在第一列中,第二列的长度在第二列中 像这样:

[["123|N1-G23-H40-K1-A11-C12-J12|banana|boy\n", 25],
["123|Z12|Goal|test\n", 3],
["123|F1-B23-G39-M22-Z12|some|girl\n", 13],
...]]

第二个功能:

sort { $b->[1] <=> $a->[1] }

通过第二列中的值对列表进行排序 按降序排列,结果将如下所示:

[["123|N1-G23-H40-K1-A11-C12-J12|banana|boy\n", 25],
["123|N1-G23-H40-K1-A11-C12|banana|boy\n", 21],
["123|F1-B23-G39-M22-Z12|some|girl\n", 18],
...]]

最终功能:

print map { $_->[0] }

提取第一列并打印结果。

Schwartzian transform是一种有用且高效的技术(或成语) 按列表元素的某个属性对列表进行排序。

答案 1 :(得分:0)

一种方法:

$ awk -F'|' -v OFS='|' '{ print $1, split($2, a, /-/), $2, $3, $4 }' input.txt |
    sort -t'|' -k 2nr,3 |
    cut -d'|' -f1,3,4,5
123|N1-G23-H40-K1-A11-C12-J12|banana|boy
123|N1-G23-H40-K1-A11-C12|banana|boy
123|F1-B23-G39-M22-Z12|some|girl
123|P1-G23-H40-K1|school|boy
123|E1-T23-N12|car|girl
123|V1-M12|car|girl
123|Z12|Goal|test

awk位添加一个新的第二列,该列是原始第二列中用-分隔的单词数。 sort然后通过首先以相反的数字顺序对新的第二列进行排序来对输出进行排序,对于该数字相同的每一行,以升序的字典顺序对第三列(原始第二列)进行排序。最后,cut删除了该多余的列。