【问题标题】:How to move a given number of random files on Unix/Linux OS如何在 Unix/Linux 操作系统上移动给定数量的随机文件
【发布时间】:2012-12-11 13:42:46
【问题描述】:

我正面临这个简单的任务,但我也想知道最简单快捷的方法是什么。

我的建议是将给定数量的随机文件从一个目录移动到另一个目录。此任务是创建机器学习所需的两个数据集的一部分:一个训练集和一个测试集。我的目标是从目录中移走 10% 的文件,以便获得可以测试分类器的数据卫星,并从源目录中获取训练集。

那么,对于这个“移动 n 个随机文件”任务,最紧凑的类型是什么?

提前致谢 - 像往常一样 -

【问题讨论】:

  • 如果你的文件有一个统一的、均匀分布的数字文件名模式,mv *0 otherdir 会移动 10%——它不是随机的,而是均匀分布的,甚至可能更接近你真正想要的;而且,它很容易记录和复制。
  • 很遗憾这不是我的情况,但你的建议真的很好。

标签: linux unix mv


【解决方案1】:

使用shufxargs 的组合(最好使用man 查看他们的文档):

shuf -n 10 -e * | xargs -i mv {} path-to-new-folder

上面的命令随机选择当前文件夹(*部分)的10个文件,然后将它们移动到新文件夹中。

更新

虽然更长,但人们可能会发现这个版本更容易理解:

ls | shuf -n 10 | xargs -i mv {} path-to-new-folder

shuf 只是生成标准输入的随机排列,将结果限制为 10(类似于使用 head,但可能更快)。

【讨论】:

  • 该命令在Debian/Ubuntu上测试,shuf的版本是8.25
  • @Mithril 当文件夹中有太多文件(在我的情况下超过 200K)时,我遇到了相同的 -bash: /usr/bin/shuf: Argument list too long 错误。
  • @mrwheet,例如,您可以尝试在ls 之后申请head -n <N>tail -n <N>。这将为shuf 生成更短的参数列表。如果有必要,你可以重复这个过程。
  • 太棒了。这对我有帮助。谢谢
  • 这在 mac 上不起作用。在 Mac 上你必须这样做 ls | gshuf -n 10 | xargs -I {} mv {} path-to-new-folder
【解决方案2】:

您可以使用 bash 随机生成器生成介于 0 和 32767 之间的 int 来选择是否必须将文件放入 set1 或 set2。这样就可以了:

for file in ./*; do
  val=$RANDOM
  if test $val -gt 3276; then
    mv "$file" ../set1
  else
    mv "$file" ../set2
  fi
done

【讨论】:

    【解决方案3】:

    find 的替代版本可避免文件夹出现问题。 它将 31415 个随机选择的文件复制到 /home/user/dir/

    find . -maxdepth 1 -type f | sort -R | head -31415 | xargs cp -t /home/user/dir/
    

    【讨论】:

      【解决方案4】:

      您可以使用 shuf 或 sort -R 随机播放文件列表。 但是你仍然需要取一个子集,你 可以做头/尾。

      【讨论】:

      • so ls $source_dir|sort -R|head -${tobemoved}| xargs -i mv $target_dir/{} - 或类似的东西。
      • sort -R 在 Unix 的所有变体中都不受支持,例如 OSX。
      【解决方案5】:

      这个问题已经很老了,但据记录,这适用于 OSX。

      你必须安装gshufbrew install coreutils,然后使用:

      tenpercent=$((`ls | wc -l` * 10/100))
      
      ls | gshuf -n $tenpercent | xargs -I {} mv {} destination/path/
      

      【讨论】:

        【解决方案6】:

        您也可以使用 Python 来执行此操作。我觉得这更容易。

        这是一个 python 脚本,我用来移动随机百分比的图像,该脚本还获取 CV 图像数据集通常需要的相关标签数据集。请注意,这会移动文件,因为我不希望在我的训练数据集中我的测试训练数据集。

        我使用下面的 Yolo 训练集,因为标签和图像在同一目录中,并且标签是 txt 文件。

        import numpy as np
        import os
        import random
        
        #set directories
        directory = str('/MauiData/maui_complete_sf_train')
        target_directory = str('/MauiData/maui_complete_sf_test')
        data_set_percent_size = float(0.07)
        
        #print(os.listdir(directory))
        
        # list all files in dir that are an image
        files = [f for f in os.listdir(directory) if f.endswith('.jpg')]
        
        #print(files)
        
        # select a percent of the files randomly 
        random_files = random.sample(files, int(len(files)*data_set_percent_size))
        #random_files = np.random.choice(files, int(len(files)*data_set_percent_size))
        
        #print(random_files)
        
        # move the randomly selected images by renaming directory 
        
        for random_file_name in random_files:      
            #print(directory+'/'+random_file_name)
            #print(target_directory+'/'+random_file_name)
            os.rename(directory+'/'+random_file_name, target_directory+'/'+random_file_name)
            continue
        
        # move the relevant labels for the randomly selected images
        
        for image_labels in random_files:
            # strip extension and add .txt to find corellating label file then rename directory. 
            os.rename(directory+'/'+(os.path.splitext(image_labels)[0]+'.txt'), target_directory+'/'+(os.path.splitext(image_labels)[0]+'.txt'))
        
            continue
        

        【讨论】:

          【解决方案7】:

          通常,我们使用 python 脚本或 Java 程序来执行此操作。其中任何一个都可以使用适当的 RNG 来做出随机决定,然后调用必要的调用来移动文件。

          【讨论】:

          • 很有趣,所以您建议使用 RNG...当然,移动限制 xarg 的文件不会以适当的随机选择结束。我会考虑的
          • 没有 RNG 怎么可能实现“随机”?
          • 当然,这是不可能的。我只是想从一个目录中获取一些文件,比如 ls |头-20。我想对包含数百个文件的同一目录重复此任务数百次,不会总是给出相同的结果。也许我错了?
          • 使用 bash 随机数生成器是否会被视为好建议? - 您可以从选择要移动的随机文件数量开始,然后 - 您可以将文件列出到 tmp.file - 并读取随机行以获取文件并移动它们; #!/bin/bash #Get the range file_list_no=ls -1 | wc -l` number=$RANDOM let "number %= $file_list_no" echo "选择要移动的随机文件数:$number of $file_list_no"`
          • 哇,我不知道 bash 的随机生成器。无论如何,我需要获得给定数量的随机文件。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2020-04-05
          • 2021-04-29
          • 1970-01-01
          • 1970-01-01
          • 2020-06-05
          • 1970-01-01
          • 2014-08-25
          相关资源
          最近更新 更多