【问题标题】:Linux sort showing odd behaviorLinux 排序显示奇怪的行为
【发布时间】:2014-07-02 07:12:36
【问题描述】:

我有一个脚本需要按数字顺序对多个文件进行 CAT。虽然它似乎可以很好地处理几百个文件,但我现在在处理更大的文件时遇到了一些“有趣”的结果。

相关文件已拆分为 1289 个单独的文件,分别命名为 ABC.001-1289 到 ABC.1289-1289

我正在使用“ls -gGo ABC* | sort -hk9”来列出文件,我认为这是一种人类可读的排序顺序。一切顺利,直到我击中 ABC.763-1289:

ABC.001-1289 .. ABC.763-1289
ABC.1000-1289 .. ABC.1040-1289 
ABC.764-1289 .. ABC.999-1289
ABC.1041-1289 .. ABC.1289-1289

我正在考虑某种缓冲区溢出或其他问题,但我以前从未经历过这样的事情,我有点摸不着头脑,甚至开始寻找解决问题的地方。

我尝试改变“k”值,甚至删除它,但收效甚微。

我研究得越多,我就越相信需要 KEYDEF,但我无法确定使用它的正确格式....

有什么想法吗?

【问题讨论】:

  • 我不明白你为什么使用-k9,因为这会使每个项目的密钥等于1289
  • Adrian, TBH 我只是想为“k”值找到正确的格式。我以前没有做过这样的“高级”排序,只能假设 ls 之间的空格被认为是列之间的分隔符。我尝试的任何格式,当第 764 个文件出现时,我似乎总是遇到问题。
  • 问题是您的字段有时是三个字符,有时是四个字符。我很想用sort -n -k5,8 来隔离变量项,但实际上“8”会有所不同。也许你应该先重命名三位数的文件。

标签: linux sorting


【解决方案1】:

我不想开始调试 shell 中内置的排序功能。那么为什么不在外壳之外使用不同的排序呢? 例如,我会使用 python:

#!/usr/bin/python2.7
import argparse, sys, re

parser = argparse.ArgumentParser( description='concatenate the input files by order',
                                  formatter_class=argparse.ArgumentDefaultsHelpFormatter )
parser.add_argument( 'input', nargs='+', help='the paths to the files to be concatenated' )
parser.add_argument( '-n','--nosort', action='store_true', help='use the given order instead of sorting' )
parser.add_argument( '-o','--output', default='', help='output file. Will output to stdout if empty' )
args = parser.parse_args()

def human_keys( astr ):
    """
    alist.sort(key=human_keys) sorts in human order
    From unutbu @ http://stackoverflow.com/questions/5254021
    """
    keys=[]
    for elt in re.split( '(\d+)', astr ):
        elt = elt.swapcase()
        try: 
            elt = int(elt)
        except ValueError: 
            pass
        keys.append( elt )
    return keys

if not args.nosort:
    args.input.sort( key = human_keys )

output = args.output and open( args.output, 'w' ) or sys.stdout

for path in args.input:
    with open( path, 'r' ) as in_file:
        for line in in_file:
            output.write(line)

if output != sys.stdout:
    output.close() # not really needed. But tidier. Can put it in an "atexit", but that's an overkill.

【讨论】:

    【解决方案2】:

    有点hacky,但试试这个:

     ls -gGo ABC* |cut -d "." -f 2 |sort -h
    

    ls -gGo ABC* |cut -b 5- |sort -h
    

    【讨论】:

      猜你喜欢
      • 2018-11-22
      • 2011-03-13
      • 2012-12-17
      • 2011-03-06
      • 1970-01-01
      • 2013-09-20
      • 2011-02-17
      • 2019-01-18
      • 2023-03-16
      相关资源
      最近更新 更多