如何从目录中的每个文件中选择 n 行的随机样本

如何从目录中的每个文件中选择 n 行的随机样本

我有一个包含许多文件的目录。我想要从每个文件中获得一个随机样本,并将其复制到一个新目录,其文件名与从中抽取随机样本的文件名相同。

答案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您也可以使用shufGNU 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 行,请更改headhead -n NUMwhereNUM是所需选取的行数。

相关内容