使用bash查找第一个包含字符串的文件夹名称
我想在Bash中这样做:使用bash查找第一个包含字符串的文件夹名称,bash,shell,find,Bash,Shell,Find,我想在Bash中这样做: 在当前目录中,找到名称中包含“foo”的第一个文件夹 我一直在使用find命令,但有点困惑。有什么建议吗?您可以使用查找的-quit选项: find <dir> -maxdepth 1 -type d -name '*foo*' -print -quit find-maxdepth 1-type d-name'*foo*'-print-quit 例如: dir1=$(find . -name \*foo\* -type d -maxdepth 1 -p
- 在当前目录中,找到名称中包含“foo”的第一个文件夹
我一直在使用find命令,但有点困惑。有什么建议吗?您可以使用
查找的-quit
选项:
find <dir> -maxdepth 1 -type d -name '*foo*' -print -quit
find-maxdepth 1-type d-name'*foo*'-print-quit
例如:
dir1=$(find . -name \*foo\* -type d -maxdepth 1 -print | head -n1)
echo "$dir1"
或者(关于更好的壳牌解决方案,请参见阿德里安·弗吕霍斯的答案)
或
根据@hek2mgl注释编辑的标题-n1
下一步基于@chepner的评论
dir1=$(find . -type d -maxdepth 1 -print | grep -m1 'foo')
或
这比提供的其他shell解决方案要好,因为
- 对于大型目录,它会更快,因为模式是glob的一部分,并且不会在循环中检查
- 当没有与您的模式匹配的目录时,实际工作正常(然后
${dir}
将为空)
- 它可以在任何兼容POSIX的shell中工作,因为它不依赖于
=~
操作符(如果需要,这取决于您的模式)
- 它适用于名称中包含换行符的目录(vs.
find
)
awk
命令可以简化为awk NR==1
,但最好使用head-n1
。谢谢!我也更喜欢头
尝试。我不知道为什么awk是我脑海中的第一个:)…我们怎么能得到最后一项而不是第一项呢?在MacOS上,我得到了非法选项m,(from-maxdepth选项)=>$find-maxdepth 1-type d-name'foo'| head-n1 find:inally选项--m用法:find[-H |-L |-P][EXdsx][f path]path。。。[expression]find[-H |-L |-P][-EXdsx]-f path[path…][expression]@AlexanderMills谢谢,您在MacOS/BSD上的操作是正确的路径参数是必需的。使用GNU find时可以省略它。答案已经很老了,今天我推荐-quit
选项。很遗憾你想要bash,zsh让事情变得更简单:echo*(/[1])
这两个选项看起来都很棒,谢谢!但是如何在变量中存储完整的文件夹名呢?如果变量中有foo
,请尝试-在find
命令中命名“*$variable*”..
。如果目录中有文件夹,但没有与foo
匹配的文件夹,则第二个解决方案将不起作用。然后$dir1
将设置为找到的最后一个目录。如果find
支持该解决方案,-在之后退出
-打印
将导致查找
在找到第一个文件后退出。类似地,grep-m1'foo'
将只输出其输入中第一次出现的'foo'。在这种情况下(-print-quit)它还将处理带有换行符的文件名,并且可能比shell方法更快。这比使用head或grep要优雅得多。$dir
只有在shell不将不匹配的glob视为文本字符串时才会为空。如果有许多文件与该模式匹配,您可能会溢出允许的最大参数数。@chepner我想您需要再次阅读我的代码。文字字符串将设置为$u dir,但不是$dir,因为测试的结果将为false。啊,是的,我没有注意到\u dir
和dir
之间的区别。我敢打赌,很少有目录有足够的子目录(相对于文件)来担心生成太多的参数。感谢您的支持,也感谢所有做出贡献的人。由于随机向上投票,再次进行了精彩的讨论,并想补充一点,这不受ARG_MAX
(@chepner)的约束。更多信息。
dir1=$(find . -type d -maxdepth 1 -print | grep 'foo' | head -n1)
echo "$dir1"
dir1=$(find . -type d -maxdepth 1 -print | grep -m1 'foo')
dir1=$(find . -name \*foo\* -type d -maxdepth 1 -print -quit)
pattern="foo"
for _dir in *"${pattern}"*; do
[ -d "${_dir}" ] && dir="${_dir}" && break
done
echo "${dir}"