Znajdź nazwy plików, które nie zawierają określonego ciągu

19

Chciałbym wykonać przeciwieństwo:

find . -name "*2013*"

Znajdź wszystkie pliki w bieżącym katalogu, które nie zawierają w swoich nazwach ciągu „2013”. Jak mogę to zrobić?

użytkownik1058398
źródło

Odpowiedzi:

28

Po prostu:

find . ! -name '*2013*'

Dodaj a, ! -type daby również wykluczyć pliki typu katalogu (podobnie jak on .sam) lub -type fdołączyć tylko zwykłe pliki, z wyłączeniem wszystkich innych typów plików (katalogów, fifos, dowiązań symbolicznych, urządzeń, gniazd ...).

Uważaj jednak, aby *pasowała do sekwencji 0 lub więcej znaków . Może więc zgłaszać nazwy plików, które zawierają, 2013jeśli 2013było to poprzedzone lub poprzedzone czymś, czego nie można w pełni zdekodować jako prawidłowe znaki w bieżącym języku.

Może się to zdarzyć, jeśli jesteś w lokalizacji, w której znaki mogą być kodowane na więcej niż jednym bajcie (jak w UTF-8) dla nazw plików zakodowanych w innym kodowaniu. Na przykład w ustawieniach regionalnych UTF-8 zgłosiłby Stéphane2013plik, éktóry zostałby zakodowany w zestawie znaków iso8859-15 (jako bajt 0xe9).

Najlepiej byłoby upewnić się, że nazwy plików są zakodowane w zestawie znaków ustawień regionalnych, ale jeśli nie możesz tego zagwarantować, obejdź to findw ustawieniach regionalnych języka C:

LC_ALL=C find . ! -name '*2013*'
Stéphane Chazelas
źródło
4

Wzorce plików Ksh są wystarczające:

# files with 2013
ls -d -- *2013*

# files without 2013
ls -d -- !(*2013*)

Odniesienie

Jeśli twoja powłoka jest bash, musisz uruchomić shopt -s extglobzanim będziesz mógł użyć tego wzorca (możesz go umieścić w swoim .bashrc). Jeśli twoją powłoką jest zsh, musisz uruchomić setopt ksh_glob(możesz ją włożyć .zshrc). Zsh oferuje również ls -d -- ^*2013*, co wymaga wstępnego setopt extended_glob.

W zależności od tego, co robisz z tymi nazwami plików, lsmoże nie być to właściwe polecenie do użycia. Aby przechowywać je w tablicy

filenames=( !(*2013*) )
for f in "${filenames[@]}"; do ...; done
Glenn Jackman
źródło
4
To nie powtarza się w podkatalogach i pomija pliki kropkowe (i lszwróci komunikat o błędzie, jeśli wzorzec nie pasuje do żadnego pliku). Zauważ też, że kshposortuje listę.
Stéphane Chazelas
-1

Znajdź wszystkie pliki w bieżącym katalogu, które nie zawierają określonego ciągu, tutaj „2013”:

find . ! -name "*2013*" -type f
użytkownik7194913
źródło
2
Jest to w zasadzie to samo co unix.stackexchange.com/a/102614/117549 sprzed 3 lat, tyle że dodałeś „-f”, co czyni tę odpowiedź gorszą.
Jeff Schaller