Znajdź pliki zawierające ciąg w nazwie pliku i inny ciąg w pliku?

17

Chciałbym (rekurencyjnie) znaleźć wszystkie pliki z „ABC” w nazwie pliku, które również zawierają „XYZ” w pliku. Próbowałem:

find . -name "*ABC*" | grep -R 'XYZ'

ale nie daje prawidłowego wyniku.

użytkownik997112
źródło

Odpowiedzi:

26

Jest tak, ponieważ grepnie można odczytać nazw plików do przeszukania ze standardowego wejścia. To, co robisz, to drukowanie nazw plików, które zawierają XYZ. Stosowanie find„s -execopcja zamiast:

find . -name "*ABC*" -exec grep -H 'XYZ' {} +

Od man find:

   -exec command ;
          Execute  command;  true  if 0 status is returned.  All following
          arguments to find are taken to be arguments to the command until
          an  argument  consisting of `;' is encountered.  The string `{}'
          is replaced by the current file name being processed  everywhere
          it occurs in the arguments to the command, not just in arguments
          where it is alone, as in some versions of find. 

[...]

   -exec command {} +
          This  variant  of the -exec action runs the specified command on
          the selected files, but the command line is built  by  appending
          each  selected file name at the end; the total number of invoca‐
          tions of the command will  be  much  less  than  the  number  of
          matched  files.   The command line is built in much the same way
          that xargs builds its command lines.  Only one instance of  `{}'
          is  allowed  within the command.  The command is executed in the
          starting directory.

Jeśli nie potrzebujesz rzeczywistych pasujących wierszy, a tylko listę nazw plików zawierających co najmniej jedno wystąpienie ciągu, użyj tego zamiast:

find . -name "*ABC*" -exec grep -l 'XYZ' {} +
terdon
źródło
2

W najprostszy sposób znajduję następujące polecenie:

grep -R --include="*ABC*" XYZ

lub dodaj -ido wyszukiwania bez rozróżniania wielkości liter:

grep -i -R --include="*ABC*" XYZ
R. Oosterholt
źródło
1

… | grep -R 'XYZ'nie ma sensu. Z jednej strony -R 'XYZ'oznacza rekurencyjne działanie na XYZkatalog. Z drugiej strony … | grep 'XYZ'oznacza poszukiwanie wzorca XYZna grepstandardowym wejściu. \

W systemie Mac OS X lub BSD grepbędzie traktować XYZjako wzór i narzeka:

$ echo XYZ | grep -R 'XYZ'
grep: warning: recursive search of stdin
(standard input):XYZ

GNU grepnie będzie narzekać. Raczej traktuje XYZjako wzorzec, ignoruje standardowe dane wejściowe i rekurencyjnie wyszukuje, zaczynając od bieżącego katalogu.


To, co chciałeś zrobić, było prawdopodobnie

find . -name "*ABC*" | xargs grep -l 'XYZ'

… Który jest podobny do

grep -l 'XYZ' $(find . -name "*ABC*")

… Oba wskazują, że grepnależy szukać XYZw pasujących nazwach plików.

Należy jednak pamiętać, że wszelkie białe spacje w nazwach plików powodują przerwanie tych dwóch poleceń. Możesz xargsbezpiecznie używać , używając NULjako separatora:

find . -name "*ABC*" -print0 | xargs -0 grep -l 'XYZ'

Ale użycie rozwiązania @ terdon find … -exec grep -l 'XYZ' '{}' +jest prostsze i lepsze.

200_sukces
źródło
-1

Linux Commend: ll -iR | grep „nazwa pliku”

np. Bookname.txt, a następnie użyj ll -iR | grep „Bookname” lub ll -iR | grep "name" lub ll -iR | grep „Book”

możemy wyszukiwać z częścią nazwy pliku.

Spowoduje to wyświetlenie wszystkich nazw plików pasujących z bieżącego i podfolderów

Perija Samy
źródło
To tylko częściowa odpowiedź, ponieważ nigdy nie odnosi się do części pytania dotyczącej „przeszukiwania pliku”. Znacznie bardziej wydajne jest również stosowanie wzorców globowania nazw plików, prawdopodobnie w połączeniu z, findjak pokazano w niektórych innych odpowiedziach.
Kusalananda