Znajdź pliki w wielu nazwach folderów

44

Staram się lista wszystkich plików z dir1, dir2, dir3i dir4które mogą być w dowolnym miejscu w podkatalogu mojego cwdpomocą findpolecenia. Próbowałem następujących bezskutecznie:

find . -type f -regextype posix-egrep -regex 'dir1/.+|dir2/.+|dir3/.+|dir4/.+'

Próbowałem posix-extendedteż. Jak mogę wyświetlić te pliki?

Aaron
źródło
odnaleźć . -type f -regextype sed -regex ". * / dir [1-4] / [a-z0-9] *" .. najkrótsza jak dotąd odpowiedź :) patrz odpowiedź poniżej .. unix.stackexchange.com/a/390333 / 242983
alpha_989

Odpowiedzi:

59

A jeśli chcesz szukać trzy foldery o nazwie foo, bari bazdla wszystkich *.pyplików, użyj polecenia:

find foo bar baz -name "*.py"

więc jeśli chcesz wyświetlić pliki z dir1 dir2 dir3użyciafind dir1 dir2 dir3 -type f

Spróbuj tego find . \( -name "dir1" -o -name "dir2" \) -exec ls '{}' \;

harish.venkat
źródło
Powinienem był to wyjaśnić. Mogę nie mieć ścieżki do plików, które chciałbym wyszukać. Wiem tylko, że są to podkatalogi bieżącego reż.
Aaron,
użyj ./dirzamiastdir
harish.venkat
Katalog nadal musiałby znajdować się w cwd, może być o dwa poziomy niższy (np. ./path/to/dir1), W którym to przypadku ./dir1nie istniałby.
Aaron,
zredagował odpowiedź.
harish.venkat,
8

Najlepiej jest użyć dyrektywy -path:

find .  \( -type f -and -path '*/dir1/*' -or -path '*/dir2/*' -or -path '*/dir3/*' -or -path '*/dir4/*' \)

Co oznacza: znajdź wszystkie pliki w bieżącym katalogu, w których na ścieżce znajduje się „dir1” lub „dir2” lub „dir3” lub „dir4”.

Okresowa konserwacja
źródło
Masz nawias w niewłaściwym miejscu. Zobacz także -ai -odla standardowego odpowiednika GNU -and/ -or.
Stéphane Chazelas
4

Po prostu, aby wszyscy wiedzieli. Dodanie .*/przed każdym dirrozwiązało problem, ponieważ regexwydaje się pasować do pełnej ścieżki.

Aaron
źródło
3

To mój pierwszy pomysł po przeczytaniu poprzednich odpowiedzi:

find . -type f -regextype posix-egrep -regex ".*/(dir1|dir2|dir3|dir4)/.+"

To bierze pod uwagę, że wyrażenie regularne musi pasować do całej nazwy pliku, i jest łatwiejsze do zrozumienia.

Ronin Tom
źródło
2

Próbka szybkiego (!) Znajdowania określonych plików (log_dostępu) w wielu lokalizacjach określonych przez symbol wieloznaczny (katalog domowy) i ogólny katalog logów apache2 z zastosowaniem filtrowania nazw w celu wykluczenia logów ssl i starych logów gzip. Nie odpowiada bezpośrednio na pytanie tutaj, ale może być przydatne dla kogoś, kto znalazł te instrukcje (jak ja).

find / \( -path "*var/log/apache2*" -o -path "*home/*/logs*" \) -type f  -name "*access_log" ! -name "*ssl*"

Uważaj na spacje, szczególnie w pobliżu \(i \).

Nawiasem mówiąc, użyłem go do apachetop, aby znaleźć najbardziej aktywne strony na moim serwerze.

apachetop -d1 -s9 -p $(find / \( -path "*var/log/apache2*" -o -path "*home/*/logs*" \) -type f  -name "*access_log" ! -name "*ssl*" -print | sed 's/^/-f '/)
Kristjan Adojaan
źródło
2

nie musisz podawać nazwy katalog od katalog1 do katalog4, jeśli używasz wyrażenia regularnego

find . -type f -regextype sed -regex ".*/dir[1-4]/[^/]*"
  • type f: znajdź pliki, a nie katalogi
  • regextype sed: używa wyrażenia regularnego sed
  • regex: wyszukuje za pomocą wyrażenia regularnego na całej ścieżce
  • ".*/dir[1-4]/[a-z0-9]*":. * na początku oznacza dowolną liczbę znaków, które mogą być typu (char / number / backslash (/) itp.); dir [1-4] oznacza szukanie „dir”, po którym następuje liczba od 1 do 4; / [^ /] * stwierdza, że ​​po dir1-4 pomija nazwy ścieżek, które zawierają /, więc zwraca tylko pliki z katalogu dir1-dir4 i ignoruje wszystkie podkatalogi, które mogą znajdować się w dir1-dir4.

utworzyłeś katalog do przetestowania: https://github.com/alphaCTzo7G/stackexchange/tree/master/linux/findSolution04092017

alpha_989
źródło
(1) Być może nigdy nie znamy dokładnej sytuacji ani wymagań Aarona, ale inne odpowiedzi podjęły ostrożną decyzję, że ma cztery katalogi, których nazwy nie są określone. (Mogą one być red, green, bluei yellowczy mogą one być John, Paul, Georgei Ringo.) Twoja odpowiedź zakłada, że są one dosłownie dir1 , dir2, dir3i dir4. … (
Scott
(Ciąg dalszy)… (2) Dlaczego zakładasz, że Aaron nie chce przeszukiwać podkatalogów? Wygląda na to, że mówi. (3) Czemu ograniczenie wyszukiwania do plików, których nazwy zawierają tylko małe litery i cyfry (z wyjątkiem rzeczy jak foo_bar, foo.txti FOO)? (4) Dlaczego twój tekst wyjaśnia, /[^/]*kiedy twoja odpowiedź go nie używa?
Scott
Cześć Scott, to jest twój komentarz.
alpha_989
(1-3). wspomina „Próbuję wyświetlić listę wszystkich plików z katalogu dir1, dir2, dir3 i dir4 ”, które mogą znajdować się w dowolnym miejscu jako podkatalog mojego cwd , co oznacza, że ​​dir1-dir4 może być gdziekolwiek, ale chce znaleźć odpowiedni plik w katalogu dir1-dir4. oczywiście, jeśli nie jest to katalog1-katalog4, musisz zmienić go na konkretne nazwy, używając czerwonego \ | niebieskiego \ | zielonego \ | itd.
alpha_989,
4. literówka tam .. Użyłem [a-z0-9] * przed .. potem uświadomiłem sobie, że [^ /] * jest krótszy i bardziej obejmujący .. zapomniałem go zmienić, kiedy to opublikowałem. Dziękujemy za uważne komentarze.
alpha_989,
0

Wiem, że określiłeś, że używając find, ale tylko w celu pokazania innych opcji, których można użyć, możesz użyć xargs:

find . -type d | grep -E "dir1$|dir2$" | xargs ls  

find . -name "dir1" -or -name "dir2" | xargs ls

Możesz mieć plik o nazwie „foldery” zawierający coś takiego:

$ cat folders
dir1
dir2
dir3
dir4

Następnie możesz zrobić coś takiego:

$ cat folders | xargs -I % find . -type d -name % | xargs ls
./Documents/dir1:
file1  file2  file3  file4

./Documents/dir2:
file1  file2  file3  file4

./Documents/dir3:
file1  file2  file3  file4

./Documents/dir4:
file1  file2  file3  file4

xargs, moim zdaniem, czuję się bardziej wszechstronny niż find -exec. Możesz także zrobić szalone rzeczy

$ cat << EOF | xargs -I {} find ~ -name "{}" | xargs ls
> dir1
> dir2
> dir3
> EOF
/home/user/Documents/dir1:
file1  file2  file3  file4

/home/user/Documents/dir2:
file1  file2  file3  file4

/home/user/Documents/dir3:
file1  file2  file3  file4
Cuauhtli
źródło