2012-03-07 18 views

Odpowiedz

11

Czy tu czegoś brakuje? Z pewnością całe to wyrażenie i/lub pętla nie jest konieczna, jedno-liniowy wykona zadanie. Również rozwiązania "for foo in $()" zawiodą, gdy w nazwach ścieżek znajdą się spacje.

Wystarczy użyć dirname dwukrotnie xargs, aby rodzic rodzica ...

# 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 {} 

Produkuje

./hht 
./wee1 
+0

I czy mogę zrobić, aby znaleźć permsissions wynikowego katalogu find. -name '.user_repo.log '| xargs -i {} dirname {} | xargs -i {} dirname {} | xargs ll – Rajeev

+0

Zakładając, że ll, do którego się odnosisz, jest powszechnie używanym aliasem dla "ls -lA", a następnie nie. xargs będzie uruchamiał tylko komendy, a nie aliasy. Jednak można zamiast tego "xargs ls -lA" ... – Adam

+0

Ostrzegamy, flaga '-i' dla' xargs' jest wymieniona jako przestarzała, najlepiej użyj flagi '-I'. –

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

EDIT: Niestety brakowało że chcesz katalog dziadka.

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

Można zrobić coś takiego:

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

gdzie xargs wykorzystuje expr match wyodrębnić część, która zaczyna się od . aż do pierwszego meczu w katalogu między znakami ukośnik (/dir/).

Alternatywna wersja użyciu sed byłby następujący:

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

@trojanfoe ma rację; this jest tylko sposobem, aby dostać to, aby bezpiecznie pracować z dowolny pliku, i prawie każdy polecenia w pętli:

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

Jeśli chcesz to echo tylko unikalne nazwy:

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

Jakiś konkretny powód, dla którego używasz innego deskryptora pliku? –

+0

Jeśli chcesz coś zrobić ze stdin wewnątrz pętli. Jest wyjaśnione na powyższym linku. – l0b0

2

Można to zrobić łatwo z opcjami formatowania działaniem find-printf (patrz man find).

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

Z man page:

Screenshot of find manpage

%h\n będzie drukować ścieżkę dla każdego pliku na nowej linii.

Należy pamiętać, że -printf jest tylko GNU. To nie zadziała na MacOS (system BSD).

0
find -type f -exec bash -c 'echo "${1%/*}"' bash {} \; 
Powiązane problemy