Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash unix对2个字段的排序数字顺序_Bash_Unix_Sorting_Sed_Awk - Fatal编程技术网

Bash unix对2个字段的排序数字顺序

Bash unix对2个字段的排序数字顺序,bash,unix,sorting,sed,awk,Bash,Unix,Sorting,Sed,Awk,我需要使用unix sort对一些数据进行排序,但我无法准确地理解正确的语法,数据看起来像 3.9.1 Step 10: 3.9.1 Step 20: 3.8.10 Step 20: 3.10.2 Step 10: 3.8.4 Step 90: 3.8.4 Step 100: 3.8.4 Step 10: 我想先使用主要编号,然后使用步骤编号对其进行排序,例如,上面排序的数据如下所示 3.8.4 Step 10: 3.8.4 Step 90: 3.8.4 Step 100: 3.8.10 St

我需要使用unix sort对一些数据进行排序,但我无法准确地理解正确的语法,数据看起来像

3.9.1 Step 10:
3.9.1 Step 20:
3.8.10 Step 20:
3.10.2 Step 10:
3.8.4 Step 90:
3.8.4 Step 100:
3.8.4 Step 10:
我想先使用主要编号,然后使用步骤编号对其进行排序,例如,上面排序的数据如下所示

3.8.4 Step 10:
3.8.4 Step 90:
3.8.4 Step 100:
3.8.10 Step 20:
3.9.1 Step 10:
3.9.1 Step 20:
3.10.2 Step 10:
我在这个网站上找到了按第一个数字排序的方法:

sort -t. -k 1,1n -k 2,2n -k 3,3n

但是我现在正在努力按照第三列步骤编号进行排序,而不干扰第一个排序

如何将
步骤
转换为
排序
,然后再转换回来?我相信这会得到你想要的结果:

cat your-file.txt \
    | sed -e 's/ Step \(.*\):$/.\1/g' \
    | sort -t. -k1,1n -k2,2n -k3,3n -k4,4n \
    | sed -e 's/\(.*\)\.\(.*\)$/\1 Step \2:/g'

(此处仅使用
cat
进行说明。如果它只是一个常规文件,则可以将其传递给第一个
sed

有一篇关于重新设计Unix
排序的精彩文章(《构建工作排序程序的理论与实践》,J P Linderman,AT&T贝尔实验室技术期刊,1984年10月),不幸的是,这在互联网上是不可用的,AFAICT(我在大约一年前看过,没有找到它;我刚才又看了一遍,可以找到它的参考文献,但找不到文章本身)除此之外,文章还演示了对于UNIX <代码>排序< /COD>,比较时间远远大于移动数据的成本(当您认为比较必须比较每行确定的字段时,并不奇怪),但是移动“数据”只是一个切换指针的问题。一个结果是,他们建议按照建议去做;映射键以便于比较。他们表明,即使是一个简单的脚本解决方案,也可以比让排序真正努力工作节省时间

因此,您可以考虑使用不太可能自然出现在数据文件中的字符(例如Control-a)作为关键字段分隔符

sed 's/^\([^.]*\)[.]\([^.]*\)[.]\([^ ]*\) Step \([0-9]*\):.*/\1^A\2^A\3^A\4^A&/' file |
sort -t'^A' -k1,1n -k2,2n -k3,3n -k4,4n |
sed 's/^.*^A//'
第一个命令是硬命令。它标识4个数字字段,并输出它们,以所选字符分隔(上面写着
^A
,键入Control-A),然后输出原始行的副本。然后,排序会对前四个字段进行数字排序,最后的
sed
命令会从每行的前端剥离,直到并包括最后一个控件-a,再次返回原始行。

已更新

这将生成您指定的输出:

sed 's/Step /Step./' data|sort -t. -n -k1,1 -k2,2 -k3,3 -k4|sed 's/Step./Step /'
结果:

3.8.4 Step 10:
3.8.4 Step 90:
3.8.4 Step 100:
3.8.10 Step 20:
3.9.1 Step 10:
3.9.1 Step 20:
3.10.2 Step 10:
这种排序的挑战在于排序字段由
“.
(用于版本号)和默认空白(用于步骤号)定义。不能为同一个排序命令指定多个/不同的字段分隔符。将多个排序与不同的字段分隔符结合使用不会产生正确的输出


此解决方案是通过“代码< >代码>”临时替换“空代码空间> <代码> > .'/CODE>,使所有排序字段可以用同一个字符(<代码>)''/c> >分隔。排序完成后,<代码> > '/COD>再次被替换为空白。

这可能对您有用:

 sort -k3,3n file | sort -nst. -k1,1 -k2,2 -k3,3
或者一个非常不确定的问题:

 sort -nt. -k1,1 -k2,2 -k3,3 -k3.7 file
第一种使用两种类型:

  • 排序-k3,3n
    按步骤排序
  • sort-nst.-k1,1-k2,2-k3,3
    按主要数字排序,但保持步长顺序
  • 第二个有效,但仅当第三个主要数字保持在100以下时有效

    或许:

    sed 's/ /./2' file | sort -nt. -k1,1 -k2,2 -k3,3 -k4,4 | sed 's/\./ /3'
    

    当我尝试你在示例数据上给出的命令行时,它会生成你说想要的答案…@jacobm,重新检查第3列,它的排序错误我在solaris 10上,如果这有区别的话,是的,第3列仍然不正确可能重复您使用排序的-n选项转换为数值吗?我希望得到一个整洁的结果er解决方案仅使用排序,但我想这也会起作用。+1 up将查看是否有其他人知道不同的排序way@jdex我找到了一个解决方案,我相信,请看看这是否是您问题的可接受答案。+1以上,我真的想避免修改数据,因为我提供的不是完整的数据集。每个ste都有一个字符串描述p(有时也包含“步骤”)。看起来似乎没有其他方法了though@jdex这真让我困惑(字面上),所以在我说这不可能完成之后,我想了很多很多。我仍然不认为仅仅因为涉及到不同的字段分隔符,单独使用
    sort
    就可以了,但这是一个具有挑战性的问题,所以要解决它。您可以始终发布一组更具代表性的数据,以确保为所有案例找到一个有效的解决方案。我确信本页上的一些解决方案可以为此进行调整。我认为第一个解决方案可以工作,但我在solaris 10上使用的sort版本没有-s选项。@jdex抱歉,我猜
    -s
    是GNU功能。
    sed
    解决方案可能会help@FrankComputer:相关的,肯定的-它引用了林德曼,但不是sa我的东西。另请看,我提到了您询问的Bentley论文和其他一些。我们可以在这里得到一个简短的预览:对于那些具有学术研究权限(或咳嗽Sci中心)的人,DOI是10.1002/j.1538-7305.1984。tb00067.x