对多个文件进行排序并合并

对多个文件进行排序并合并

我想以相反的顺序对多个文本文件进行排序,然后合并/cat 到一个文本文件。

a.txt

0   33.1
2   33.0
10  21.1
20  21.8

b.txt

0   30.1
2   33.0
10  28.1
20  27.8

等等*.txt文件

我想要这样的输出

20  21.8
10  21.1
2   33.0
0   33.1
20  27.8
10  28.1
2   33.0
0   30.1

我不想这样

20  21.8
20  27.8
10  21.1
10  28.1
2   33.0
2   33.0
0   33.1
0   30.1

我尝试了这些代码

for file in *.txt ; do 
   sort -nrk 1,1 *.txt > "$file" ; 
done

我也尝试过

sort -m *.txt

但这些代码的输出不是我想要的。

我正在寻找使用sort merge paste cat或其他一些相关选项的解决方案。

非常感谢您的帮助。

答案1

单独对文件进行排序,并将整个输出重定向到结果文件:

for file in *.txt ; do 
   sort -k1,1rn < "$file"
done > file.concatenated

(这里重要的是输出文件没有.txt扩展名,因为它是首先通过重定向创建的)。

或者,如果您想就地对文件进行排序(将它们重写为自身排序):

set -- *.txt
ok=true
for file do
  sort -o "$file" -k1,1rn -- "$file" || ok=false
done
"$ok" && cat -- "$@" > file.concatenated

这种两阶段方法使我们能够在创建串联文件之前检测文件排序中的问题。

您的第一个循环不起作用,因为您.txt在循环的每次传递中传递了完整的文件列表。

sort -m是将已经排序的文件合并到排序的输出中。这与你想要的相反。您想要对尚未排序的文件进行排序,并仅连接结果而不将它们合并到已排序的输出中。

在这里,文件似乎是按正向顺序排序的。如果您可以相信情况总是如此,那么您应该能够反转它们,这比反转排序更有效。

为此,GNU 系统有一个tac命令和其他几个命令tail -r(但请注意,某些实现仅采用一个文件参数,因此您可能需要使用这些命令进行循环)。

tac -- *.txt > file.concatenated

另请注意,这与解决关系时-k1,1rn不同。-rnk1,1当两行进行相等比较时,sort将对整行进行词法比较(例如此处,1 a1 b与 进行相等比较-k1,1n,但在词法1 a上位于前面1 b)。

通过该-r选项,最后的比较是相反进行的。当r将标志添加到关键规范之一时,这并不适用。

GNUsort必须-s禁用最后的比较,这将导致它保留同等比较的行的原始顺序。

相关内容