Zauważyłem niedawno, że specyfikacje POSIXfind
nie obejmują -maxdepth
podstawowego.
Dla tych, którzy go nie znają, głównym celem -maxdepth
jest ograniczenie o ile poziomów find
zejdzie. -maxdepth 0
powoduje przetwarzanie tylko argumentów wiersza poleceń; -maxdepth 1
obsługuje tylko wyniki bezpośrednio w argumentach wiersza poleceń itp.
Jak mogę uzyskać zachowanie równoważne z podstawowym systemem innym niż POSIX, -maxdepth
używając tylko opcji i narzędzi określonych przez POSIX?
(Uwaga: Oczywiście mogę uzyskać ekwiwalent -maxdepth 0
po prostu -prune
jako pierwszy operand, ale nie obejmuje to innych głębokości).
-depth -2
,-depth 1
... podejście może być postrzegane jako lepsze niż GNU-maxdepth
/-mindepth
-maxdepth
/-mindepth
istnieją rozsądne alternatywy (zauważ, że-path
jest to najnowszy dodatek do POSIX). Alternatywy dla-timexy
lub-mtime -3m
(lub-mmin -3
) są o wiele bardziej kłopotliwe. Niektórzy lubią-execdir
/-delete
nie mają niezawodnej alternatywy.Odpowiedzi:
Możesz użyć,
-path
aby dopasować daną głębokość i przycinać tam. Na przykładbyłoby maxdepth 1, ponieważ
*
pasuje do.
,*/*
dopasowuje./dir1
i*/*/*
dopasowuje,./dir1/dir2
które są przycinane. Jeśli używasz bezwzględnego katalogu początkowego, musisz również dodać do niego wiodącą/
pozycję-path
.źródło
/*
z końca wzoru, wyjąć-o
operatora i uzyskać ten sam wynik?*
pasuje/
również, więc reża/b/c/d/e
pasowałby-path */*
, niestety.a/b/c/d/e
nigdy nie zostałby osiągnięty , ponieważ-prune
zostałby zastosowany doa/b
...-prune
i-o
zostały usunięte. Jeśli utrzymasz-prune
problem, problem polega na tym, że*/*
nic nie będzie pasowało na poziomie wyższym niż maxdepth, np. Pojedynczy kataloga
.Podejście @ meuh jest nieefektywne jak jego
-maxdepth 1
podejście pozwala nadalfind
czytać zawartość katalogów na poziomie 1, aby później je zignorować. Nie będzie również działał poprawnie z niektórymifind
implementacjami (w tym GNUfind
), jeśli niektóre nazwy katalogów zawierają sekwencje bajtów, które nie tworzą prawidłowych znaków w ustawieniach regionalnych użytkownika (np. Dla nazw plików z innym kodowaniem znaków).jest bardziej kanonicznym sposobem implementacji GNU
-maxdepth 1
(lub FreeBSD-depth -2
).Ogólnie rzecz biorąc, to
-depth 1
chcesz (-mindepth 1 -maxdepth 1
), ponieważ nie chcesz brać pod uwagę.
(głębokość 0), a następnie jest jeszcze prostsze:Dla
-maxdepth 2
to staje się:I tu właśnie występują problemy z nieprawidłowymi postaciami.
Na przykład, jeśli masz katalog o nazwie,
Stéphane
któryé
jest zakodowany w zestawie znaków iso8859-1 (aka latin1) (bajt 0xe9), jak to było najczęściej w Europie Zachodniej i Ameryce do połowy 2000 roku, to bajt 0xe9 nie jest poprawny znak w UTF-8. Zatem w ustawieniach regionalnych UTF-8*
symbol wieloznaczny (z niektórymifind
implementacjami) nie będzie pasował,Stéphane
ponieważ*
ma 0 lub więcej znaków, a 0xe9 nie jest znakiem.Mój
find
(gdy dane wyjściowe trafiają do terminala) wyświetla ten nieprawidłowy bajt 0xe9 jak?
wyżej. Widać, żeSt<0xe9>phane/Chazelas
to nie byłoprune
d.Możesz obejść ten problem, wykonując:
Należy jednak pamiętać, że wpływa to na wszystkie ustawienia regionalne
find
i każdą uruchomioną aplikację (np. Za pośrednictwem-exec
predykatów).Teraz naprawdę dostaję
-maxdepth 2
ale é w drugim Stéphane poprawnie zakodowanym w UTF-8 jest wyświetlane jako??
bajty 0xc3 0xa9 (uważane za dwa pojedyncze niezdefiniowane znaki w ustawieniach regionalnych C) kodowania é UTF-8 niedrukowalne znaki w ustawieniach regionalnych C.A gdybym dodał a
-name '????????'
, otrzymałbym niewłaściwą Stéphane (kodowaną w iso8859-1).Aby zastosować zamiast dowolnych ścieżek
.
, wykonaj następujące czynności:dla
-mindepth 1 -maxdepth 1
lub:dla
-maxdepth 2
.Nadal zrobiłbym:
Po pierwsze, ponieważ powoduje to, że ścieżki są krótsze, co zmniejsza prawdopodobieństwo zbyt długiego napotkania ścieżki lub listy argumentów zbyt długich , ale także obejścia faktu, że
find
nie może obsługiwać argumentów arbitralnej ścieżki (z wyjątkiem-f
FreeBSDfind
), ponieważ będzie się dusić wartości$dir
jak!
lub-print
...W
-o
połączeniu z negacją jest powszechną sztuczką do uruchamiania dwóch niezależnych zestawów-condition
/-action
infind
.Jeśli chcesz uruchomić
-action1
na spotkaniu plików-condition1
i niezależnie-action2
na spotkaniu plików-condition2
, nie możesz:Podobnie jak w
-action2
przypadku plików, które się spełniają oba warunki.Ani:
Jak
-action2
nie będzie działać na plikach, które spełniają oba warunki.działa tak,
\( ! -condition1 -o -action1 \)
jakby rozwiązał prawdę dla każdego pliku. Zakłada się, że-action1
to działanie (jak-prune
,-exec ... {} +
), które zawsze zwraca wartość true . Dla takich działań-exec ... \;
może być zwracana wartość false , możesz dodać inną,-o -something
gdzie-something
jest nieszkodliwa, ale zwraca wartość true, tak jak-true
w GNUfind
lub-links +0
lub-name '*'
(choć zwróć uwagę na problem dotyczący nieprawidłowych znaków powyżej).źródło
Natknąłem się na problem, w którym potrzebowałem sposobu ograniczenia głębokości podczas wyszukiwania wielu ścieżek (zamiast tylko
.
).Na przykład:
Doprowadziło mnie to do alternatywnego podejścia z użyciem -regex. Istotą jest:
Tak więc powyższe byłoby:
Bez nazwy pliku:
Wreszcie
-maxdepth 2
zmiany wyrażeń regularnych:'(dir1|dir2)/([^/]*/){0,1}[^/]*$'
źródło
-maxdepth
z wieloma ścieżkami wyszukiwania.