Załóżmy, że mam folder zawierający .txt , .pdf i inne pliki. Chciałbym wymienić „inne” pliki (tzn. Pliki, które nie mają rozszerzeń .txt lub .pdf ). Czy masz jakieś porady, jak to zrobić?
Wiem, jak wyświetlić listę plików bez danego rozszerzenia. Na przykład, jeśli chcę wyświetlić listę wszystkich plików oprócz plików .txt , to albo
find -not -iname "*.txt"
lub
ls | grep -v '\.txt$' | column
wydaje się działać. Ale jak mogę wyświetlić wszystko oprócz plików .txt lub .pdf ? Wydaje się, że muszę użyć jakiegoś logicznego „lub” w find
lub grep
.
ls
vsfind
vs globowanie może się różnić w przypadku ukrytych plików dot.find
będzie przechodzić przez podkatalogi, jak rekurencyjnyls
. Użyj-maxdepth 1
z,find
aby uzyskać bardziej podobne zachowaniels
.Odpowiedzi:
Zakładając, że ktoś ma odpowiednią wersję
ls
, jest to prawdopodobnie najprostszy sposób:Jeśli chcesz iterować we wszystkich podkatalogach:
źródło
ls
Opcje GNU nie są przenośne.ls
tak naprawdę nie należy do przenośnych skryptów, więc zakładam, że OP pyta tylko o interaktywne użycie.Znajdź wsparcie
-o
Potrzebujesz nawiasu, aby mieć pierwszeństwo. Znajdź robi wiele rzeczy; Proponuję przeczytać na stronie podręcznika.
Możesz także wykonać wejście lub wejście
grep
(ale tak naprawdę nie powinieneś analizować danych wyjściowychls
)źródło
ls
?find
strony polecam z całego serca artykuły Unix Power Tools na tematfind
, takie jak docstore.mik.ua/orelly/unix3/upt/ch09_06.htm i docstore.mik.ua/orelly/unix3/upt/ch09_12.htmfind . NOT ( *.txt OR *.pdf )
Przy
bash
rozszerzonym globowaniu (włącz za pomocąshopt -s extglob
) glob!(*.txt|*.pdf)
powinien działać. Możesz przekazać ten glob bezpośrednio do dowolnego polecenia pobierającego argumenty pliku, w tym między innymils
.źródło
-d
aby tego uniknąć:ls -d !(*.txt|*.pdf)
W
zsh
zextendedglob
:lub
Lub z
kshglob
(tak, to znaczy ksh globbing, a nie „bash Extended globbing”):Pamiętaj jednak, że wykluczają one również pliki kropek.
ksh93 ma
FIGNORE
(błędną) funkcję:źródło
Jest to równoważne z poleceniem z operatorem OR, ze względu na prawa De Morgana .
źródło
Jak sugeruje derobert, najlepszym rozwiązaniem jest użycie
find
. Jednak może w rzeczywistości wykorzystać wynik w rurociągu z innych komend.GNU (i niektóre BSD)
find
obsługują-print0
predykat, który nakazuje wydrukować nazwę pliku zakończoną znakiem NUL , który to znak nie jest dozwolony w nazwie pliku i gwarantuje, że nie dojdzie do kolizji. Innym poleceniom można polecić użycie NUL jako ogranicznika wejściowego.Najważniejszym z nich jest GNU
xargs
, który uruchamia określone polecenie i przekazuje mu listę plików jako argumenty wiersza poleceń. Chcesz uruchomićxargs -r0
w połączeniu z find na-print0
przykład:Spowoduje to bezpieczne wydrukowanie długiej listy katalogów wszystkich plików pdf i txt , w tym tych ze spacją lub niezadrukowanymi znakami w nazwie.
Możesz go również używać z GNU
tar
w następujący sposób:To buduje plik tar.gz wszystkich plików, których nazwy nie kończą się na .tar.gz
rsync
akceptuje również pliki rozdzielane zerami z-0
parametrem, podobnie jak kilka innych. Alexargs
jest to klej, którego zwykle używasz do tego rodzaju celów. Albo to, albofind
jest-exec
funkcja.źródło
tar
Przykład komenda jest dobry. Jednak dla większości celów-exec
jest to lepsze dopasowanie.Jeśli nie masz podkatalogu
powinien również działać!
Ale
jest powszechnym sposobem.
źródło
Jako uzupełnienie, jeśli używasz powłoki kompatybilnej z bash, możesz użyć zmiennej GLOBIGNORE, aby wykluczyć zmiany z dopasowania wzorca. Od mężczyzny:
W twoim konkretnym przypadku:
Uwaga: uruchamiam to polecenie jako podpowłokę (używając nawiasu), aby nie zmieniać zmiennej środowiskowej GLOBIGNORE mojej interaktywnej powłoki.
źródło