在随机化之前根据先前的文件顺序重新排序行

时间:2017-08-16 15:09:51

标签: linux bash awk sed grep

我在file1中有以下几行:

line 1text
line 2text
line 3text
line 4text
line 5text
line 6text
line 7text

使用命令cat file1 | sort -R | head -4,我在file2中获得以下内容:

line 5text
line 1text
line 7text
line 2text

我想将这些行(不是数字,与file1的顺序相同)订购到以下file3中:

line 1text
line 2text
line 5text
line 7text

实际数据没有数字。有什么简单的方法吗?我正在考虑做一个grep并在循环中找到第一个实例。但是,我相信你有经验的人知道一个更简单的解决方案。您的积极意见得到了高度赞赏。

3 个答案:

答案 0 :(得分:5)

您可以使用行号进行装饰,选择四行随机行,按行号排序并删除行号:

=OFFSET($C$5,MATCH($A$1,$B$5:$B$108,0)-COUNTIF($C$5:$C$108,">"&0)-1,0,COUNTIF($C$5:$C$108,">"&0),1)

$ nl -b a file1 | shuf -n 4 | sort -n -k 1,1 | cut -f 2- line 2text line 5text line 6text line 7text 的{​​{1}}选项可确保空行也已编号。

请注意,这会将所有-b a加载到内存中,如ghoti所述。为了避免这种情况(以及通常更智能的解决方案),我们可以使用(GNU)nl的不同功能:其file1选项采用数字范围并将每个数字视为一条线。要从输入文件shuf获取四个随机行号,我们可以使用

-i

现在,我们必须准确打印这些行。 Sed可以做到这一点;我们只需将上一个命令的输出转换为sed脚本,然后使用file1运行sed。一起来:

shuf -n 4 -i 1-$(wc -l < file1)
  • sed -n -f -以数字方式对行号进行排序。这不是严格要求的,但如果我们知道最高行号是最后一行,我们可以在之后退出sed,而不是一无所获地读取文件的其余部分。
  • shuf -n 4 -i 1-$(wc -l < file1) | sort -n | sed 's/$/p/;$s/p/{&;q}/' | sed -n -f - file1 sort -n添加到每一行。对于最后一行,我们追加sed 's/$/p/;$s/p/{&;q}/来停止处理文件。

    如果p的输出看起来像

    {p;q}

    然后sed命令将其变为

    sort
  • 27 774 670 541 进程27p 774p 670p 541{p;q} ,使用上面sed命令的输出作为sed的说明。 sed -n -f - file1会抑制我们不想要的行的输出。

该命令可以参数化并放入shell函数中,将文件名和行数作为参数打印出来:

file1

一样使用
-n

答案 1 :(得分:1)

cat可以添加行号:

$ cat -n file
 1  line one
 2  line two
 3  line three
 4  line four
 5  line five
 6  line six
 7  line seven
 8  line eight
 9  line nine

因此您可以将其用于decorate, sort, undecorate

$ cat -n file | sort -R | head -4 | sort -n

您还可以使用awk使用随机数字和行索引进行修饰(如果您的sort在OS X上缺少-R):

$ awk '{print rand() "\t" FNR "\t" $0}' file | sort -n | head -4
0.152208    4   line four
0.173531    8   line eight
0.193475    6   line six
0.237788    1   line one

然后使用行号进行排序并删除装饰(根据您使用catawk进行装饰,取决于一列或两列):

$ awk '{print rand() "\t" FNR "\t" $0}' file | sort -n | head -4 | cut -f2- | sort -n | cut -f2-
line one
line four
line six
line eight

答案 2 :(得分:0)

另一种解决方案可能是对整个文件进行排序

sort file1 -o file2

在file2上选择随机行

shuf -n 4 file2 -o file3