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
Find files and print only their parent directories
提问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文件在哪里,我们都需要打印父目录(即hht和wee1.)如何做到这一点?
$ 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:
从手册页:


%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 {} \;

