首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在bash编程中不冗余地从目录中随机获取文件?

如何在bash编程中不冗余地从目录中随机获取文件?
EN

Stack Overflow用户
提问于 2016-04-18 14:14:13
回答 3查看 51关注 0票数 0

我想再问一次巴什的事。我想从目录中随机获取文件。例如,有

13.525文件在一个目录中。

我随便拿了个文件

gr123.adl,对于下一个随机文件,我想要该文件

gr123.adl不再被选中。

我应该如何用bash语言实现它呢?

谢谢你以前的帮助

问候古什蒂纳医学硕士

EN

回答 3

Stack Overflow用户

发布于 2016-04-19 13:33:41

如果可能的话,我可能会用另一种语言更好地处理这种情况。例如,在python中,您可以像

代码语言:javascript
复制
files = os.listdir('.')
random.shuffle(files)
for path in files:
    # do your code test stuff on path

bash中拥有返回下一个文件名的函数比较困难,但是如果您只想以随机顺序对文件进行操作,我们可以按照@shelter的建议使用数组,并结合在this answer中找到的随机函数。在这里,我们将对数组中的所有文件名进行洗牌,然后对它们进行迭代:

代码语言:javascript
复制
shuffle() {
   local i tmp size max rand

   # $RANDOM % (i+1) is biased because of the limited range of $RANDOM
   # Compensate by using a range which is a multiple of the array size.
   size=${#array[*]}
   max=$(( 32768 / size * size ))

   for ((i=size-1; i>0; i--)); do
      while (( (rand=$RANDOM) >= max )); do :; done
      rand=$(( rand % (i+1) ))
      tmp=${array[i]} array[i]=${array[rand]} array[rand]=$tmp
   done
}

array=( * )
shuffle

for((i=0; i<${#array[*]}; i++ )); do
    printf "Operating on %s\n" "${array[i]}"
    # do whatever test makes sense on "${array[i]}"
done

如果您真的想要一个返回"next“文件的函数,我们可以将其设置为保存当前文件名的变量,这与上面的操作略有不同。因此,我们将用另一个函数定义替换底部的for循环,循环如下:

代码语言:javascript
复制
next_file() {
    if [[ "$array_ind" -ge "${#array[*]}" ]]; then
        cur=""
    else
        cur="${array[array_ind++]}"
    fi
}

array_ind=0

# now we use next_file whenever we want `cur` to get the next file:
next_file
while [[ ! -z "$cur" ]]; do
    printf -- "--%s--\n" "$cur"
    next_file
done
票数 2
EN

Stack Overflow用户

发布于 2016-04-18 14:21:35

您可以尝试以下几种方法:

代码语言:javascript
复制
 ls | sort -R | while read f; do echo $f; done

sort -R正在对文件进行洗牌,while循环确保得到所有文件1乘1。

编辑:

如果您的一些文件包含控制字符(如\n),则可以尝试以下操作:

代码语言:javascript
复制
 OLDIFS=$IFS; IFS=$(echo -en "\b"); for f in $(ls -b | sort -R); do echo "$f"; done; IFS=$OLDIFS

这将输入字段分隔符更改为\b (将其更改为任何不匹配所有文件名中任何字符的适当内容)。

ls -b列出具有控制字符的文件。

for循环是一个接一个地接收文件。

最后,将IFS设置为其原始值。

票数 1
EN

Stack Overflow用户

发布于 2016-04-18 19:05:39

如果您真的想要这样做,那么您需要一个函数,它将接受参数并跟踪文件。

代码语言:javascript
复制
rand_file() {
   track=~/${PWD##*/}.rand_file
   touch $track

   while read f; do
      if ! grep -q "$f" $track; then
         echo $f| tee -a $track
         break
      fi
   done < <(ls |sort -R)
}

我们使用的是for循环,所以如果我们已经得到目录中的每个文件,那么它就会干净地退出。我们在以目录命名的文件中进行跟踪,这样如果同一个命名的文件在其他地方,我们就不会将它作为先前返回的文件使用--注意,这意味着您必须在PWD中使用它,您可以编写更好的代码,但是我现在不打算删除这个部分。一旦返回所有文件,该函数就会退出,而不返回任何内容。您可以删除主目录中的文件以重置进程。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36696516

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档