утилита grep в сценарии оболочки - PullRequest
3 голосов
/ 09 октября 2009

Я пытаюсь преодолеть ограничение нашей файловой структуры. Я хочу собрать всю серию файлов в известном месте. Если я делаю стандартный grep из командной строки

(grep -i searchpattern known_dir/s*.sql) 

Я получаю следующую ошибку:

ksh: /usr/bin/grep: 0403-027 The parameter list is too long.

поэтому у меня есть немного для цикла, который выглядит следующим образом:

searchfor=$1
for i in /$ENV_VAR_DIR/s*.sql
do
  grep -i $searchfor $i
done

Когда я выполняю это, у меня возникает пара проблем:

  1. это дает мне строку кода, но без имени файла, мне нужны оба
  2. -l очевидно дает мне только путь / имя файла, который я хочу обрезать путь, который я просто выполняю из моего домашнего каталога.

Ответы [ 7 ]

3 голосов
/ 09 октября 2009

Я бы порекомендовал следующее:

$ find known_dir -name 's*.sql' -print0 | xargs -0 grep -i searchpattern

С помощью xargs вы можете изменять максимальное количество файлов, которые вы передаете grep каждый раз, используя опцию -n.

Опции -print0 и -0 являются защитой от пробелов в именах файлов.

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

2 голосов
/ 12 октября 2009

В качестве хака вы также можете указать / dev / null для своей команды grep, чтобы получить -l для вывода списка файлов, однако ваш метод будет медленным, так как он использует цикл оболочки и запускает процесс grep для каждого файла. find и xargs ваши друзья здесь, как уже упоминалось.

Возможно, вы могли бы использовать скрипт findrepo , который, кажется, работает так, как вам нужно.

1 голос
/ 09 октября 2009

find ./known_dir/ -name "s * .sql" | xargs grep -i searchpattern

1 голос
/ 09 октября 2009
ls | read fname; do
    grep searchpattern $fname /dev/null
done

Это делает две вещи для вас.

  1. Вам не нужно раскрывать все файлы одновременно, они обрабатывают их по одному.
  2. Если перечислить / dev / null в качестве второго файла, он не будет ничего совпадать, но получит grep для печати имени файла. Gnu grep имеет опцию принудительного вывода имени файла, но это будет работать на любом Unix.

Другая традиционная вещь, которую нужно сделать с этим шаблоном проектирования оболочки, - заполнить цикл find.

find . -name "*.sql" | read fname; do
    grep searchpattern $fname /dev/null
done

Возможно, вы также захотите сделать searchpattern быть $1.

0 голосов
/ 15 ноября 2010
easy_install grin    
grin -I "*.sql" searchpattern

Показать только имя файла

grin -I "*.sql" -l searchpattern
0 голосов
/ 09 октября 2009

Вы хотите либо ack , либо ухмылка .

0 голосов
/ 09 октября 2009

grep -H заставит имя файла ставиться перед каждой выходной строкой так же, как если бы вы выполняли исходную одиночную команду.

Самый простой способ получить только имя файла, будь то -H или -l, состоит в том, чтобы каталог был вашим текущим рабочим каталогом при запуске команды:

searchfor=$1
cd /$ENV_VAR_DIR
for i in s*.sql
do
  grep -Hi $searchfor $i
done
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...