如何用其他文本行作为键对文本行进行排序?

时间:2019-05-18 15:03:20

标签: bash unix awk command-line-interface

基本上等效于CLI中的“ sort-by”方法。

样本输入文件(file1.txt):

one
three
five
eleven
thirteen
sixteen

另一个输入文件(file2.txt,其中列出了file1.txt中相应行的长度):

3
5
4
6
8
7

所需的输出(将file1.txt中的行按file2.txt中的行进行排序,在这种情况下,将其按数字进行排序;换句话说,按行的长度对file1.txt中的行进行排序):

one
five
three
eleven
sixteen
thirteen

我已经创建了simple Perl script来执行此操作。用法示例:

% sort-by-lines file1.txt file2.txt
% sort-by-lines /etc/passwd <(perl -nE'say length' /etc/passwd)

但是,我想知道更基本的Unix命令(sortcut等)的组合是否也可以以相对简单的方式完成同样的工作。

1 个答案:

答案 0 :(得分:4)

您只是想按每行的长度对文件进行排序吗?在任何UNIX机器上的任何外壳中使用标准工具,都是:

awk -v OFS='\t' '{print length(), NR, $0}' file | sort -k1,2n | cut -f3-

例如:

$ cat file
other stuff
text
foo
stuff
bar

$ awk -v OFS='\t' '{print length(), NR, $0}' file | sort -k1,2n | cut -f3-
foo
bar
text
stuff
other stuff

如果不是,那么请编辑您的问题,以阐明您要执行的操作以及您的实际问题是什么。


更新-根据您在问题中添加的输入:

$ paste file2.txt file1.txt | sort -k1,2n | cut -f2-
one
five
three
eleven
sixteen
thirteen

请注意,这不一定会保留相同长度的行的顺序-您需要在-s上添加GNU sort(“稳定”)选项才能做到这一点:< / p>

paste file2.txt file1.txt | sort -s -k1,2n | cut -f2-

或执行仅bash操作:

paste file2.txt <(cat -n file1.txt) | sort -k1,2n | cut -f3-

或可移植到所有shell / Unix的代码:

awk -v OFS='\t' 'NR==FNR{a[NR]=$0;next} {print a[FNR], FNR, $0}' file2.txt file1.txt | sort -k1,2n | cut -f3-

或使用显式的临时文件或此处文档进行某些操作。