使用awk排序ngram单词

时间:2013-12-06 06:55:23

标签: bash sorting awk

我有以下内容,并希望使用awk命令进行排序

 capital of the country
 capital of 
 capital 
 capital of the 
 capital is 
 capital is the   
 capital is the like 

我希望这些按照

排序
 capital
 capital is
 capital of
 capital is the 
 capital is the like
 capital of the 
 capital of the country

是否可以使用awk命令进行与上述完全相同的排序,还是需要通过编程来处理它?<​​/ p>

2 个答案:

答案 0 :(得分:3)

这在Python中非常简单:

import sys

# get input filename from command line
_, infile = sys.argv

# read the data in to a list
with open(infile, "rt") as f:
    lines = f.readlines()

# define a function to use for sorting
def ngram_key(line):
    words = line.split()
    # We want to sort by, first, number of words; second, the text.
    # Return a tuple with two values, number of words and the text.
    return (len(words), line) # same number of words should sort together

# sort the lines using the desired rule
lines.sort(key=ngram_key)

# print the lines to standard output
print(''.join(lines))

但是AWK没有Python排序的key=功能。如果Python适合您,这个答案将起作用。如果你真的需要AWK,那么我建议使用DSU(装饰,排序,不装饰)。将行存储在数组中,但在每行前面加上单词数(作为固定长度的字符串)。然后所有具有相同字数的行将一起排序,就像在Python程序中一样。完成排序后,删除固定长度的数字,然后排序。 DSU也被称为“Schwartzian变换”。

http://en.wikipedia.org/wiki/Schwartzian_transform

所以这是使用上述技术在AWK中的工作解决方案:

{
    # Store lines prefixed by number of words in line.
    # As numbers are fixed-length and zero-prefixed, an ASCII
    # sort will also be a numeric sort.
    a[NR] = sprintf("%04d%s", NF, $0)
}

END {
    # sort the stored lines
    asort(a)
    # strip off the prefix and print each line
    for (i = 1; i <= NR; ++i) {
        line = substr(a[i], 5)
        print(line)
    }
}

恕我直言,Python更清晰,更容易理解。在Python中,您必须从命令行显式读取参数,而在AWK中则不需要;但在其他方面,我认为Python更容易理解。

编辑:所以,这是输出。这是你想要的吗?我以为是,但我只是再次看你的示例输出,这是不一样的。如果您的示例完全正确,那么我实际上并不了解您要做的事情。

这是您按字数排序时获得的结果,其次是单词:

capital
capital is
capital of
capital is the
capital of the
capital is the like
capital of the country

此外,AWK版本中存在一个错误,它没有打印最后一行。固定的。

答案 1 :(得分:2)

您可以使用管道

实现steveha引用的Schwartzian变换
awk '{print NF, $0}' file.txt | sort -k1,1n -k2 | cut -f2- -d' '
capital 
capital is 
capital of 
capital is the   
capital of the 
capital is the like 
capital of the country

内的所有内容,以及sortcut的标注

awk '{print NF, $0 | "sort -k1,1n -k2 | cut -f2- -d\\  "}' file.txt