首页 > 解决方案 > 按同一列的两个子字符串排序,只有一个反转

问题描述

我有一个看起来像这样的文件:

2836344588  ...  ...  N  fs1q
2836344589  ...  ...  N  fp2q
2836374222  ...  ...  N  fp3q
2836374223  ...  ...  N  fp6q
2836374224  ...  ...  N  fp7q
2836384836  ...  ...  N  fs2q
2836384837  ...  ...  N  fp1q
2836384838  ...  ...  N  fp4q
2836384839  ...  ...  N  fp5q
2836384957  ...  ...  N  fs3q
2836384958  ...  ...  N  fs7q
2836404416  ...  ...  N  fs5q
2836414186  ...  ...  N  fs6q
2836434267  ...  ...  N  fs4q

我想按第五列的第二个和第三个字符对其进行排序:第二个字符的排序应该按字母倒序进行(s应该在前面p),第三个字符的排序应该按常规进行(即非-reversed) 数字顺序。

我以为我可以通过以下方式实现这一目标:

sort -k5.2r -k5.3n

但这会导致:

2836384958  ...  ...  N  fs7q
2836414186  ...  ...  N  fs6q
2836404416  ...  ...  N  fs5q
2836434267  ...  ...  N  fs4q
2836384957  ...  ...  N  fs3q
2836384836  ...  ...  N  fs2q
2836344588  ...  ...  N  fs1q
2836374224  ...  ...  N  fp7q
2836374223  ...  ...  N  fp6q
2836384839  ...  ...  N  fp5q
2836384838  ...  ...  N  fp4q
2836374222  ...  ...  N  fp3q
2836344589  ...  ...  N  fp2q
2836384837  ...  ...  N  fp1q

其中第五列的第三个字符的排序也是相反的。

如何对该文件进行排序,以便反向排序仅发生在第二个字符上(所有 's' 行都在所有 'p' 行之前)而不是第三个字符?换句话说,我如何获得这个期望的输出:

2836344588  ...  ...  N  fs1q
2836384836  ...  ...  N  fs2q
2836384957  ...  ...  N  fs3q
2836434267  ...  ...  N  fs4q
2836404416  ...  ...  N  fs5q
2836414186  ...  ...  N  fs6q
2836384958  ...  ...  N  fs7q
2836384837  ...  ...  N  fp1q
2836344589  ...  ...  N  fp2q
2836374222  ...  ...  N  fp3q
2836384838  ...  ...  N  fp4q
2836384839  ...  ...  N  fp5q
2836374223  ...  ...  N  fp6q
2836374224  ...  ...  N  fp7q

提前谢谢了。

标签: shellsortingunixfish

解决方案


因为反向标志适用-k于该命令中的所有内容,所以您可以通过两个sort命令管道而不是尝试同时执行它们?(我将文本保存在文件中s.txt)。它对我来说也更适合这个-b选项......?

[我-s还需要该选项以使其不会继续超出指定字段的排序。]

sort s.txt -n -k5.3,5.3 -b | sort -r -k5.2,5.2 -b -s

输出按第 2 列反向排序,然后按数字排序(我将输入文件修改为更具可变性)。需要用 指定开始和停止列,。所以现在在第 5 个字段中,第二列按 t->p 排序,第三列 1->9。

2836384837  ...  ...  N  ft1q
2836404416  ...  ...  N  ft5q
2836414186  ...  ...  N  ft6q
2836344588  ...  ...  N  bs1q
2836384836  ...  ...  N  fs2q
2836384957  ...  ...  N  fs3q
2836434267  ...  ...  N  fs4q
2836384958  ...  ...  N  cs7q
2836344589  ...  ...  N  fp2q
2836374222  ...  ...  N  fp3q
2836384838  ...  ...  N  bp4q
2836384839  ...  ...  N  fp5q
2836374223  ...  ...  N  ap6q
2836374224  ...  ...  N  fp7q

在这种情况下,指定位置两次并使用该-s选项将确保它将排序限制在该列,而不是继续到行尾。


推荐阅读