Dom*_*red 0 linux bash awk grep sed
我有以下几行file1
:
line 1text
line 2text
line 3text
line 4text
line 5text
line 6text
line 7text
Run Code Online (Sandbox Code Playgroud)
通过命令,cat file1 | sort -R | head -4
我得到以下内容file2
:
line 5text
line 1text
line 7text
line 2text
Run Code Online (Sandbox Code Playgroud)
我想在下面命名行(不是数字,只是相同的顺序file1
)file3
:
line 1text
line 2text
line 5text
line 7text
Run Code Online (Sandbox Code Playgroud)
实际数据没有数字.有什么简单的方法吗?我正在考虑做一个grep并在循环中找到第一个实例.但是,我相信你经验丰富的人知道一个更简单的解决方案.您的积极意见得到高度赞赏.
您可以使用行号进行装饰,选择四行随机行,按行号排序并删除行号:
$ nl -b a file1 | shuf -n 4 | sort -n -k 1,1 | cut -f 2-
line 2text
line 5text
line 6text
line 7text
Run Code Online (Sandbox Code Playgroud)
在-b a
以选项nl
可以确保还空行进行编号.
请注意,这会将所有内容加载file1
到内存中,如ghoti所指出的那样.为了避免这种情况(以及通常更智能的解决方案),我们可以使用(GNU)的不同功能shuf
:它的-i
选项采用数字范围并将每个数字视为一条线.要从输入文件中获取四个随机行号file1
,我们可以使用
shuf -n 4 -i 1-$(wc -l < file1)
Run Code Online (Sandbox Code Playgroud)
现在,我们必须准确打印这些行.Sed可以做到这一点; 我们只需将上一个命令的输出转换为sed脚本并运行sed sed -n -f -
.全部一起:
shuf -n 4 -i 1-$(wc -l < file1) | sort -n | sed 's/$/p/;$s/p/{&;q}/' |
sed -n -f - file1
Run Code Online (Sandbox Code Playgroud)
sort -n
用数字排序行号.这不是严格要求的,但是如果我们知道最后一行的最后一行,我们可以在之后退出sed,而不是一无所获地读取文件的其余部分.sed 's/$/p/;$s/p/{&;q}/
附加p
到每一行.对于最后一行,我们追加{p;q}
停止处理该文件.
如果输出sort
看起来像
27
774
670
541
Run Code Online (Sandbox Code Playgroud)
然后sed命令将其转换为
27p
774p
670p
541{p;q}
Run Code Online (Sandbox Code Playgroud)sed -n -f - file1
进程file1
,使用上面的sed命令的输出作为sed的说明.-n
抑制我们不想要的行的输出.
该命令可以参数化并放入shell函数中,将文件名和行数作为参数打印:
randlines () {
fname=$1
nlines=$2
shuf -n "$nlines" -i 1-$(wc -l < "$fname") | sort -n |
sed 's/$/p/;$s/p/{&;q}/' | sed -n -f - "$fname"
}
Run Code Online (Sandbox Code Playgroud)
用得像
randlines file1 4
Run Code Online (Sandbox Code Playgroud)