У меня есть следующие команды. Где бы ни находился файл .user.log
, нам нужно распечатать родительские каталоги (i.e hht
и wee1
.) Как это можно сделать?
$ cd /nfs//office/ && find . -name '.user.log'
./hht/info/.user.log
./wee1/info/.user.log
У меня есть следующие команды. Где бы ни находился файл .user.log
, нам нужно распечатать родительские каталоги (i.e hht
и wee1
.) Как это можно сделать?
$ cd /nfs//office/ && find . -name '.user.log'
./hht/info/.user.log
./wee1/info/.user.log
Я что-то пропустил. Конечно, все это регулярное выражение и/или цикл не нужны, один-лайнер выполнит эту работу. Также "для foo в $()" решения не удастся, если в именах путей есть пробелы.
Просто используйте 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 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 {}
Выдает
./hht
./wee1
for file in $(find /nfs/office -name .user.log -print)
do
parent=$(dirname $(dirname $file))
echo $parent
done
ИЗМЕНИТЬ: Простите, что вам нужен каталог grandparent.
Вы можете легко сделать это с помощью параметров форматирования действия -printf
find
(см. man find
).
cd /nfs//office/ && find . -name '.user.log' -printf "%h\n"
./hht/info
./wee1/info
На странице man:
%h\n
будет печатать путь для каждого файла в новой строке.
Обратите внимание, что -printf
- только GNU. Он не будет работать на macOS (система BSD).
@trojanfoe имеет правильную идею; this - это просто способ заставить его работать безопасно с любым именем файла и почти любой командой в цикле:
while IFS= read -r -d '' -u 9
do
echo "$(dirname -- "$(dirname -- "$REPLY")")"
done 9< <( find "/nfs/office/" -name '.user.log' -print0 )
Если вы хотите, чтобы он отображал только уникальные имена:
while IFS= read -r -d '' -u 9
do
echo "$(dirname -- "$(dirname -- "$REPLY")")"
done 9< <( find "/nfs/office/" -name '.user.log' -print0 ) | sort -u
find /nfs/office -name '.user.log' | while read line
do
echo $line | awk -F/ '{print $(NF-1),$NF}'
done
Вы можете сделать что-то вроде этого:
cd /nfs/office/ && find . -name '.user.log' | xargs -n1 -I{} expr match {} '\(\.\(\/[^/]*\/\)\?\)'
где xargs
использует expr match
для извлечения части, которая начинается с .
, до первого совпадения каталога между косой чертой (/dir/
).
Альтернативная версия с использованием sed
будет следующей:
cd /nfs/office/ && find . -name 'file.txt' | sed -r 's|(\./([^/]*/)?).*|\1|'
find -type f -exec bash -c 'echo "${1%/*}"' bash {} \;