我有一个行数未知的文本文件.我需要随机抓取一些这些行,但我不希望有任何重复的风险.
我试过这个:
jot -r 3 1 `wc -l<input.txt` | while read n; do
awk -v n=$n 'NR==n' input.txt
done
Run Code Online (Sandbox Code Playgroud)
但这很丑陋,并不能防止重复.
我也试过这个:
awk -vmax=3 'rand() > 0.5 {print;count++} count>max {exit}' input.txt
Run Code Online (Sandbox Code Playgroud)
但这显然也不是正确的方法,因为我甚至不能保证获得max
线路.
我被卡住了.我该怎么做呢?
如果您可以使用 Python(将 更改10
为您想要的):
python -c 'import random, sys; print("".join(random.sample(sys.stdin.readlines(), 10)).rstrip("\n"))' < input.txt
Run Code Online (Sandbox Code Playgroud)
(这适用于 Python 2.x 和 3.x。)
另外,(再次将 更改10
为适当的值):
sort -R input.txt | head -10
Run Code Online (Sandbox Code Playgroud)
如果jot
您的系统上有 ,那么我猜您正在运行 FreeBSD 或 OSX 而不是 Linux,因此您可能没有类似的工具rl
或sort -R
可用的工具。
不用担心。不久前我不得不这样做。试试这个:
$ printf 'one\ntwo\nthree\nfour\nfive\n' > input.txt
$ cat rndlines
#!/bin/sh
# default to 3 lines of output
lines="${1:-3}"
# default to "input.txt" as input file
input="${2:-input.txt}"
# First, put a random number at the beginning of each line.
while read line; do
printf '%8d%s\n' $(jot -r 1 1 99999999) "$line"
done < "$input" |
sort -n | # Next, sort by the random number.
sed 's/^.\{8\}//' | # Last, remove the number from the start of each line.
head -n "$lines" # Show our output
$ ./rndlines input.txt
two
one
five
$ ./rndlines input.txt
four
two
three
$
Run Code Online (Sandbox Code Playgroud)
这是一个 1 行示例,它还使用 awk 更干净地插入随机数:
$ printf 'one\ntwo\nthree\nfour\nfive\n' | awk 'BEGIN{srand()} {printf("%8d%s\n", rand()*10000000, $0)}' | sort -n | head -n 3 | cut -c9-
Run Code Online (Sandbox Code Playgroud)
请注意,如果您想明确使用它,不同版本的sed
(在 FreeBSD 和 OSX 中)可能需要该-E
选项,而不是-r
在正则表达式中处理 ERE 或 BRE 方言,尽管我测试的所有内容都适用于 BRE 中的转义边界。((HP/UX 等)的旧版本sed
可能不支持此表示法,但只有当您已经知道如何执行此操作时,您才会使用这些表示法。)