bash 打印 'find' linux 命令找到匹配项的目录

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18989034/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 06:40:22  来源:igfitidea点击:

Print the directory where the 'find' linux command finds a match

linuxbashubuntu

提问by Disco

I have a bunch of directories; some of them contain a '.todo' file.

我有一堆目录;其中一些包含“.todo”文件。

/storage/BCC9F9D00663A8043F8D73369E920632/.todo
/storage/BAE9BBF30CCEF5210534E875FC80D37E/.todo
/storage/CBB46FF977EE166815A042F3DEEFB865/.todo
/storage/8ABCBF3194F5D7E97E83C4FD042AB8E7/.todo
/storage/9DB9411F403BD282B097CBF06A9687F5/.todo
/storage/99A9BA69543CD48BA4BD59594169BBAC/.todo
/storage/0B6FB65D4E46CBD8A9B1E704CFACC42E/.todo

I'd like the 'find' command to print me only the directory, like this

我想要'find'命令只打印目录,就像这样

/storage/BCC9F9D00663A8043F8D73369E920632
/storage/BAE9BBF30CCEF5210534E875FC80D37E
/storage/CBB46FF977EE166815A042F3DEEFB865
...

here's what I have so far, but it lists the '.todo' file as well

这是我到目前为止所拥有的,但它也列出了“.todo”文件

#!/bin/bash
STORAGEFOLDER='/storage'
find $STORAGEFOLDER -name .todo  -exec ls -l {} \;

Should be dumb stupid, but i'm giving up :(

应该是愚蠢的愚蠢,但我要放弃:(

回答by konsolebox

To print the directory name only, use -printf '%h\n'. Also recommended to quote your variable with doublequotes.

要仅打印目录名称,请使用-printf '%h\n'. 还建议用双引号引用您的变量。

find "$STORAGEFOLDER" -name .todo -printf '%h\n'

If you want to process the output:

如果要处理输出:

find "$STORAGEFOLDER" -name .todo -printf '%h\n' | xargs ls -l

Or use a loop with process substitution to make use of a variable:

或者使用带有进程替换的循环来使用变量:

while read -r DIR; do
    ls -l "$DIR"
done < <(exec find "$STORAGEFOLDER" -name .todo -printf '%h\n')

The loop would actually process one directory at a time whereas in xargs the directories are passed ls -lin one shot.

循环实际上一次处理一个目录,而在 xargs 中,目录是ls -l一次性传递的。

To make it sure that you only process one directory at a time, add uniq:

要确保一次只处理一个目录,请添加 uniq:

find "$STORAGEFOLDER" -name .todo -printf '%h\n' | uniq | xargs ls -l

Or

或者

while read -r DIR; do
    ls -l "$DIR"
done < <(exec find "$STORAGEFOLDER" -name .todo -printf '%h\n' | uniq)

If you don't have bash and that you don't mind about preserving changes to variables outside the loop you can just use a pipe:

如果您没有 bash 并且您不介意在循环外保留对变量的更改,则可以使用管道:

find "$STORAGEFOLDER" -name .todo -printf '%h\n' | uniq | while read -r DIR; do
    ls -l "$DIR"
done

回答by TRiG

The quick and easy answer for stripping off a file name and showing only the directory it's in is dirname:

去除文件名并仅显示其所在目录的快速简便的答案是dirname

#!/bin/bash
STORAGEFOLDER='/storage'
find "$STORAGEFOLDER" -name .todo  -exec dirname {} \;