我正在尝试创建一个简单的Shell脚本,其中包括从当前工作目录中选择一个随机目录,然后导航到该目录。
任何人都可以说明如何列出所有目录,并从此列表中随机选择一个目录吗?
我试图避免将所有目录列入文本文件,只是从该文件中选择一个随机行(这很简单)。
我最初的尝试包括使用ls -d */
命令仅列出目录。该命令在输入终端时有效,但返回错误:
ls: */: No such file or directory
当我尝试将其实现到此脚本中时:
DIR_LIST=` ls -d */`
echo "$DIR_LIST"
答案 0 :(得分:4)
else{
System.out.println("Wrong value entered. Please try again");
continue;
}
否find . -maxdepth 1 -type d ! -path . | shuf -n 1
版本:
shuf
修改:根据评论改进代码。
答案 1 :(得分:2)
您看到的错误消息表示当前目录发生以使无(非隐藏)子目录< / strong> - 脚本的工作目录可能与您期望的cd
不同,与期望的目录不同。第一
然而,除此之外,它更好not to parse the output of ls
;
直接使用pathname expansion (globbing) 更简单,更健壮 - 见下文。
注意:最初,这个答案仅包含一个基于bash
数组的解决方案,该解决方案已被替换为多行字符串解决方案,并给出了通用标题问题。
问题标记为osx
,其中有两个含义:
shuf
。
gshuf
通过Homebrew安装(brew install coreutils
)。jot
已预先安装;虽然远不等同于shuf
,但 能够从一系列整数中选择一个随机数。基于 jot
的解决方案:
dirs=$(printf '%s\n' */) # collect subdir. names, each on its own line
randomLineNum=$(jot -r 1 1 $(wc -l <<<"$dirs")) # pick random line number
randomDir=$(sed -n "$randomLineNum{p;q;}" <<<"$dirs") # extract random dir. name
cd "$randomDir" # use the randomly selected dir.
printf '%s\n' */
打印所有目录名称(终止/
);每个人都有自己的路线。
find
; glob */
足以匹配所有子目录。jot -r 1 1 $(wc -l <<<"$dirs")
会返回1和$dirs
(wc -l <<<"$dirs"
)中行数之间随机选择的整数,即子目录数。sed -n '<lineNumber>{p;q;}'
是一个sed
成语,只打印(p
)具有指定数字的行,然后退出(q
)处理该文件。符合POSIX标准的解决方案:
注意:如果您不能认为存在jot
,shuf
或bash
,则此功能非常方便。
dirs=$(printf '%s\n' */)
randomLineNum=$(awk -v count="$(printf '%s\n' "$dirs" | wc -l)" \
'BEGIN { srand(); print 1 + int(rand()* count) }')
randomDir=$(printf '%s\n' "$dirs" | sed -n "$randomLineNum{p;q;}")
cd "$randomDir"
printf '%s\n' "$dirs" | wc -l
计算$dir
awk -v count=<lineCount> 'BEGIN { srand(); print 1 + int(rand()* count) }'
使用awk
打印1到1之间的随机数:
srand()
为随机生成器播种,rand()
返回随机浮动&gt; = 0和&lt; 1;通过乘以行数,转换为整数并加1,返回随机数&gt; = 1&lt; =行数。为了完整起见,让我们看一下shuf
解决方案:
shuf
最简单但效率低下的解决方案:
printf '%s\n' */ | shuf -n 1
shuf -n 1
随机播放所有输入行,然后只打印洗牌行的第一个。这是低效的,因为即使只需要 1 随机行, shuf
也总是将所有输入行一次读入内存,并将所有洗牌,而不是随机挑选1个;但是,少数几行可能无关紧要。
稍微繁琐,但效率更高shuf
解决方案:
请注意,此解决方案类似于基于jot
的解决方案。
dirs=$(printf '%s\n' */)
randomLineNum=$(shuf -n 1 -i 1-"$(wc -l <<<"$dirs")")
randomDir=$(sed -n "$randomLineNum{p;q;}" <<<"$dirs")
cd "$randomDir"
shuf -n 1 -i 1-"$(wc -l <<<"$dirs")"
在<{1}}($dirs
)中的行数和1之间的范围内随机播放整数,并仅打印 1 (第一个)洗牌数字的wc -l <<<"$dirs"
,有效地产生一个随机的行号。-n 1
不同,后者只是在范围内选择单个整数。答案 2 :(得分:1)
试试这个:
ls -d */ | shuf -n 1
shuf 从您的输出中选择随机目录。
您的脚本将如下所示:
DIR_LIST=`ls -d */`
echo "$DIR_LIST" | shuf -n 1
答案 3 :(得分:0)
您可以尝试
find . -maxdepth 1 -type d
而不是使用ls。我现在不在终点站,所以我无法测试。它可能是maxdepth 0。