Find files and print only their parent directories

半城伤御伤魂 提交于 2019-12-05 11:11:19

问题


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

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

回答1:


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.

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

# 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



回答2:


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

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

From the man page:

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

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




回答3:


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.




回答4:


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

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 unique names:

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



回答5:


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



回答6:


You could do something like this:

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

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

An alternative version using sed would be as follows:

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



回答7:


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


来源:https://stackoverflow.com/questions/9597433/find-files-and-print-only-their-parent-directories

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!