Linux 查找文件并仅打印其父目录

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9597433/
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-08-06 05:01:27  来源:igfitidea点击:

Find files and print only their parent directories

linuxshellcommand

提问by Rajeev

I have the following commands. Wherever the .user.logfile is present, we need to print the parent directories (i.e hhtand wee1.) How can this be done?

我有以下命令。无论.user.log文件在哪里,我们都需要打印父目录(即hhtwee1.)如何做到这一点?

$ cd /nfs//office/ && find . -name '.user.log'
./hht/info/.user.log
./wee1/info/.user.log

采纳答案by Adam

Am I missing something here. Surely all this regex and/or looping is not necessary, a one-liner will do the job. Also "for foo in $()" solutions will fail when there are spaces in the path names.

我在这里错过了什么。当然,所有这些正则表达式和/或循环都不是必需的,单行代码就可以完成这项工作。当路径名中有空格时,“for foo in $()”解决方案也会失败。

Just use dirname twice with xargs, to get parent's parent...

只需将 dirname 与 xargs 一起使用两次,即可获得父级的父级...

# make test case
mkdir -p /nfs/office/hht/info
mkdir -p /nfs/office/wee1/info
touch /nfs/office/hht/info/.user.log
touch /nfs/office/wee1/info/.user.log

# parent's parent approach
cd /nfs//office/ && find . -name '.user.log' | xargs -I{} dirname {} | xargs -I{} dirname {}

# alternative, have find print parent directory, so dirname only needed once...
cd /nfs//office/ && find . -name ".user.log" -printf "%h\n"  | xargs -I{} dirname {}

Produces

生产

./hht
./wee1

回答by trojanfoe

for file in $(find /nfs/office -name .user.log -print)
do
    parent=$(dirname $(dirname $file))
    echo $parent
done

EDIT: Sorry missed that you want the grandparent directory.

编辑:抱歉错过了您想要祖父目录。

回答by xda1001

find /nfs/office -name '.user.log' | while read line
do
    echo $line | awk -F/ '{print $(NF-1),$NF}'
done

回答by jcollado

You could do something like this:

你可以这样做:

cd /nfs/office/ && find . -name '.user.log' | xargs -n1 -I{} expr match {} '\(\.\(\/[^/]*\/\)\?\)'

where the xargsuses expr matchto extract the part that starts with .until the first match of directory between slash characters (/dir/).

其中xargs使用expr match以提取开头的部分.斜杠字符之间的目录的,直到第一匹配(/dir/)。

An alternative version using sedwould be as follows:

使用的替代版本sed如下:

cd /nfs/office/ &&  find . -name 'file.txt' | sed -r 's|(\./([^/]*/)?).*||'

回答by l0b0

@trojanfoe has the right idea; thisis just a way to get it to work safely with anyfilename, and pretty much any command within the loop:

@trojanfoe 有正确的想法;只是让它安全地使用任何文件名以及循环中几乎所有命令的一种方法:

while IFS= read -r -d '' -u 9
do
    echo "$(dirname -- "$(dirname -- "$REPLY")")"
done 9< <( find "/nfs/office/" -name '.user.log' -print0 )

If you want it to echo only the uniquenames:

如果您希望它仅回显唯一名称:

while IFS= read -r -d '' -u 9
do
    echo "$(dirname -- "$(dirname -- "$REPLY")")"
done 9< <( find "/nfs/office/" -name '.user.log' -print0 ) | sort -u

回答by rosencreuz

You can do this easily with the formatting options of the -printfaction of find(see man find).

您可以使用 操作的格式选项轻松完成此-printf操作find(请参阅 参考资料man find)。

cd /nfs//office/ && find . -name '.user.log' -printf "%h\n"
./hht/info
./wee1/info

From the man page:

手册页

Screenshot of find manpage

查找联机帮助页的屏幕截图

%h\nwill print path for each file on a new line.

%h\n将在新行上打印每个文件的路径。

Please note that -printfis GNU-only. It won't work on macOS (a BSD system).

请注意,这-printf是仅限 GNU 的。它不适用于 macOS(BSD 系统)。

回答by A T

find -type f -exec bash -c 'echo "${1%/*}"' bash {} \;