find . -type f -name '*f*' | sed -r 's|/[^/]+$||' |sort |uniq
Powyżej znajduje wszystkie pliki poniżej bieżącego katalogu ( .
), które są zwykłymi plikami ( -type f
) i mają f
gdzieś swoją nazwę ( -name '*f*'
). Następnie sed
usuwa nazwę pliku, pozostawiając tylko nazwę katalogu. Następnie lista katalogów jest sortowana ( sort
), a duplikaty usuwane ( uniq
).
sed
Komenda składa się z pojedynczego substytut. Wyszukuje dopasowania do wyrażenia regularnego /[^/]+$
i zastępuje wszystko pasujące do niego niczym. Znak dolara oznacza koniec linii. [^/]+'
oznacza jeden lub więcej znaków, które nie są ukośnikami. Oznacza /[^/]+$
to , że wszystkie znaki od ostatniego ukośnika do końca linii. Innymi słowy, odpowiada to nazwie pliku na końcu pełnej ścieżki. Zatem polecenie sed usuwa nazwę pliku, pozostawiając niezmienioną nazwę katalogu, w którym plik się znajdował.
Uproszczenia
Wiele nowoczesnych sort
poleceń obsługuje -u
flagę, która czyni ją uniq
niepotrzebną. W przypadku GNU sed:
find . -type f -name '*f*' | sed -r 's|/[^/]+$||' |sort -u
I dla MacOS sed:
find . -type f -name '*f*' | sed -E 's|/[^/]+$||' |sort -u
Ponadto, jeśli find
polecenie to obsługuje, możliwe jest find
bezpośrednie wydrukowanie nazw katalogów. Pozwala to uniknąć potrzeby sed
:
find . -type f -name '*f*' -printf '%h\n' | sort -u
Bardziej niezawodna wersja (wymaga narzędzi GNU)
Powyższe wersje będą mylone z nazwami plików zawierającymi znaki nowej linii. Bardziej niezawodnym rozwiązaniem jest sortowanie ciągów zakończonych NUL:
find . -type f -name '*f*' -printf '%h\0' | sort -zu | sed -z 's/$/\n/'
uniq
do miksu bardzo pomaga, usuwając powtarzające się linie, które są już obok siebie.find . -type f -name '*f*' -printf '%h\0' | uniq -z | sort -zu | tr '\0' '\n'
. Lub jeśli twoje narzędzia są trochę starsze, to uniq może nie mieć opcji -z.find . -type f -name '*f*' -printf '%h\n' | uniq | sort -u
-E
w systemie MacOS.Dlaczego nie spróbować tego:
źródło
find
są w rzeczywistości dość rzadkie --printf
operator nie jest określony. To nie działa z BSDfind
. Zatem nie „w pełni kompatybilny z POSIX”. (Chociażsort -u
jest w POSIX .)Istnieją zasadniczo 2 metody, których można użyć do tego celu. Jeden parsuje ciąg, a drugi będzie działał na każdym pliku. Podczas analizowania ciągu użyj narzędzia takiego jak
grep
,sed
lub,awk
oczywiście, będzie on szybszy, ale oto przykład pokazujący oba, a także sposób „profilowania” 2 metod.Przykładowe dane
W poniższych przykładach wykorzystamy następujące dane
Usuń niektóre
*f*
pliki zdir1/*
:Podejście nr 1 - Analiza składni za pomocą łańcuchów
Tutaj mamy zamiar wykorzystywać następujące narzędzia,
find
,grep
, isort
.Podejście nr 2 - Analiza przy użyciu plików
Ten sam łańcuch narzędzi jak poprzednio, tyle że tym razem będziemy używać
dirname
zamiastgrep
.UWAGA: Powyższe przykłady służą
head -5
jedynie do ograniczenia ilości danych wyjściowych, z którymi mamy do czynienia w tych przykładach. Zwykle byłyby usuwane, aby uzyskać pełną listę!Porównywanie wyników
Możemy użyć,
time
aby spojrzeć na 2 podejścia.dirname
grep
Dlatego zawsze najlepiej radzić sobie z ciągami znaków, jeśli to możliwe.
Alternatywne metody analizy ciągów
grep i PCRE
sed
awk
źródło
Oto jeden uważam za użyteczny:
źródło
Ta odpowiedź bezwstydnie oparta jest na odpowiedzi SLM. To było ciekawe podejście, ale ma ograniczenia, jeśli nazwy plików i / lub katalogów mają specjalne znaki (spacja, półkolumna ...). Dobrym nawykiem jest używanie
find /somewhere -print0 | xargs -0 someprogam
.Przykładowe dane
W poniższych przykładach wykorzystamy następujące dane
Usuń niektóre
*f*
pliki zdir1/*/
:Podejście nr 1 - Analiza przy użyciu plików
UWAGA : Powyższe przykłady służą
head -5
jedynie do ograniczenia ilości danych wyjściowych, z którymi mamy do czynienia w tych przykładach. Zwykle byłyby usuwane, aby uzyskać pełną listę! również zamieńecho
dowolne polecenie, którego chcesz użyć.źródło
Z
zsh
:źródło