4

В UNIX: в папках находятся файлы с .sas (программы) и файлы с .sas7bdat (таблицы). Мне нужно найти программы (и НЕ таблицы), которые содержат текст "liasse". Я попытался, запустив эту команду:

grep -rli liasse *.sas ./

В результате я вижу имя таблицы. Какой должна быть команда для извлечения только программ?

3 ответа3

2

Это POSIX-совместимая команда, которая запускает grep для нескольких файлов одновременно:

find . -type f -name '*.sas' -exec grep -li liasse {} +


Ваша команда grep -rli liasse *.sas ./ работает не так, как вы ожидали. Давайте проанализируем, что происходит:

  1. *.sas проходит ракушку
    1. Если в текущем каталоге есть хотя бы один объект, соответствующий *.sas , все они помещаются после liasse .
    2. Если такого объекта нет, grep может получить буквальный *.sas в качестве пути для проверки (это зависит; исследовать, например, shopt -s nullglob , shopt -s failglob в bash) и выдать предупреждение.
  2. В любом случае, grep получает ./ и рекурсивно обрабатывает его при поиске liasse внутри файлов. Это обрабатывает все файлы в ./: программы, таблицы, что угодно.

Вот почему вы можете получить имя таблицы в вашем результате.


Моя команда find . -type f -name '*.sas' -exec grep -li liasse {} + запускает grep только для файлов, которые соответствуют шаблону *.sas . Важные вещи:

  • -type f выбирает только файлы. Таким образом, я предотвращаю передачу имен каталогов, совпадающих с *.sas (если есть), в grep (grep без -r любом случае должен их отклонить, но это будет менее элегантно).
  • Цитирование шаблона предотвращает слипание оболочки; find получает литерал *.sas в качестве аргумента операнда -name ; он знает, как интерпретировать такие паттерны.
  • Синтаксис find … -exec … {} + заменяет несколько объектов вместо {} . Таким образом, создается меньше (может быть, только один) процессов grep , по сравнению с find … -exec … {} \; ,
1

Вы можете использовать команду find для рекурсивного поиска всех файлов по имени, а затем запустить grep для каждого файла. Самым простым решением является опция -exec find:

find . -name '*.sas' -exec grep -li liasse {} \;

Кроме того, вы можете комбинировать find с xargs:

find . -name '*.sas' -print0 | xargs -0 grep -li liasse

Это немного лучше, потому что он выполняет grep для большого пакета файлов, а не для каждого отдельного файла.

Используя опцию -P xargs , вы можете даже запускать несколько вызовов grep параллельно.

-1

Это может быть достигнуто с

find . -type f -name "*.sas" -print0 | "xargs" -0 -e grep -liH -e liasse

Если у вас нет реализации xargs с опцией -0 , которая предназначена для передачи набора путей между find и xargs , вы можете попробовать

 find . -type f -name "*.sas" -print | "xargs" -e grep -liH -e liasse

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .