我有一个约2000个文件的目录.如何N
通过使用bash脚本或管道命令列表来选择随机的文件样本?
这是一个使用GNU sort的随机选项的脚本:
ls |sort -R |tail -$N |while read file; do # Something involving $file, or you can leave # off the while to just get the filenames done
你可以使用shuf
(来自GNU coreutils包).只需输入一个文件名列表,并要求它从随机排列中返回第一行:
ls dirname | shuf -n 1 # probably faster and more flexible: find dirname -type f | shuf -n 1 # etc..
调整该-n, --head-count=COUNT
值以返回所需行数.例如,要返回5个随机文件名,您将使用:
find dirname -type f | shuf -n 5
以下是一些不解析输出的可能性,ls
对于名称中带有空格和滑稽符号的文件,这些可能性是100%安全的.所有这些都将randf
使用随机文件列表填充数组.printf '%s\n' "${randf[@]}"
如果需要,可以轻松打印此阵列.
这个可能会多次输出相同的文件,N
需要事先知道.在这里我选择N = 42.
a=( * ) randf=( "${a[RANDOM%${#a[@]}]"{1..42}"}" )
此功能没有很好的记录.
如果事先不知道N,但你真的很喜欢以前的可能性,你可以使用eval
.但它是邪恶的,你必须确保N
不经过彻底检查就直接来自用户输入!
N=42 a=( * ) eval randf=( \"\${a[RANDOM%\${#a[@]}]\"\{1..$N\}\"}\" )
我个人不喜欢eval
这个答案!
使用更简单的方法(循环):
N=42 a=( * ) randf=() for((i=0;i如果您不希望多次使用同一个文件:
N=42 a=( * ) randf=() for((i=0;i
注意.这是旧帖子的迟到答案,但是接受的答案链接到显示可怕的bash练习的外部页面,而另一个答案并不是更好,因为它也解析了输出
ls
.对接受的答案的评论指出了Lhunath的一个很好的答案,它显然表现出良好的实践,但并没有完全回答OP.
4> silgon..:ls | shuf -n 10 # ten random files
@CiprianTomoiaga这是你可能遇到的问题的一个例子.`ls`不能保证给你"干净"的文件名,所以你不应该依赖它,句号.这些问题罕见或不寻常的事实并没有改变问题; 特别是考虑到有更好的解决方案.
@bfontaine你似乎被文件名中的换行符所困扰:).他们真的很常见吗?换句话说,是否有一些工具可以创建名称中带换行符的文件?由于作为用户,创建这样的文件名非常困难.来自互联网的文件也是如此
5> scai..:一种简单的解决方案,用于选择
5
随机文件,同时避免解析ls.它还适用于包含空格,换行符和其他特殊字符的文件:shuf -ezn 5 * | xargs -0 -n1 echo替换
echo
为要为文件执行的命令.
你是对的。我以前的解决方案不适用于包含换行符的文件名,并且可能还会破坏带有某些特殊字符的其他文件名。我已经更新了答案,使用空终止而不是换行符。
6> Mark..:如果您安装了Python(适用于Python 2或Python 3):
要选择一个文件(或任意命令中的一行),请使用
ls -1 | python -c "import sys; import random; print(random.choice(sys.stdin.readlines()).rstrip())"要选择
N
文件/行,请使用(注意N
在命令末尾,用数字代替)ls -1 | python -c "import sys; import random; print(''.join(random.sample(sys.stdin.readlines(), int(sys.argv[1]))).rstrip())" N