我有一个包含许多文件的目录。我想要从每个文件中获得一个随机样本,并将其复制到一个新目录,其文件名与从中抽取随机样本的文件名相同。
答案1
mkdir -p random_samples
find dir -type f -exec sh -c 'for n do sort -R "$n" | head >"random_samples/${n##*/}"; done' sh {} +
这将查找其中或以下的所有常规文件dir
,并对这些文件运行一个简短的 shell 脚本:
for n do
sort -R "$n" | head >"random_samples/${n##*/}"
done
这个简短的 shell 脚本将循环遍历给定的路径名(这将是由 找到的常规文件find
)并将sort -R
在每个路径名上运行。这将打乱各行,并且head
将产生每次打乱的前十行。输出将转到random_samples
文件名与原始文件相同的目录。不检查文件名冲突random_samples
。
sort -R
您也可以使用shuf
GNU coreutils 来代替。
唯一的缺点是随机样本中的行的排序将是随机的,即随机样本中的行将不会根据其在文件中的原始顺序进行排序。
为了对随机样本执行与原始文件中相同的排序,我们可以将我们的短 shell 脚本替换为
for n do
awk -v OFS="\t" "{ print NR, \$0 }" "$n" | sort -R | head | sort -n |
cut -f 2 >"random_samples/${n##*/}"
done
首先在文件的每一行后面附加行号(和一个制表符),然后我们打乱这些行并像以前一样选择前 10 行。然后,对选取的行进行数字排序,并在保存样本之前删除行号。
允许find
运行这个:
find dir -type f -exec sh -c '
for n do
awk -v OFS="\t" "{ print NR, \$0 }" "$n" | sort -R | head | sort -n |
cut -f 2 >"random_samples/${n##*/}"
done' sh {} +
要选取多于或少于 10 行,请更改head
为head -n NUM
whereNUM
是所需选取的行数。