2009-10-09 7 views
3

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

(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, очевидно, дает мне только путь/имя файла. Я хочу обрезать путь, который я просто выполняю из своего домашнего каталога.
+0

Это вопрос о программировании оболочки; он принадлежит StackOverflow, а не в другом месте. –

ответ

0

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

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

searchfor=$1 
cd /$ENV_VAR_DIR 
for i in s*.sql 
do 
    grep -Hi $searchfor $i 
done 
1
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

Остерегайтесь дорожек с пробелами! –

+0

Правда, каждый '$ fname' должен быть' '$ fname'', а' '* .sql'' должен быть' '* .sql''. – DigitalRoss

1

найти ./known_dir/ -name "s * .sql" | xargs -i Grep searchpattern

+0

извините, моя ошибка find ./known_dir/ "s * .sql" | xargs grep -i searchpattern – Vijay

+0

Работает как очарование! Я знаю, что это много спрашивает, но теперь есть способ обрезать путь к каталогу, так что все, что у меня есть, это имя файла? – 2009-10-09 15:17:37

+0

Это отлично работает. Думаю, что я хорошо с тем, что у меня есть, в конце концов, вот что я получил: для i в $ 1 do find $ i -name $ 2 | xargs grep -i $ 3 сделано – 2009-10-09 15:23:47

3

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

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

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

Параметры -print0 и -0 - это защита от пробелов в именах файлов.

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

+1

Добавьте/dev/null после шаблона поиска, и вы получите имена файлов (потому что в командной строке всегда есть как минимум два файла/dev/null и все, что было найдено find). –

+1

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

2

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

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

0
easy_install grin  
grin -I "*.sql" searchpattern 

К имени файла только шоу

grin -I "*.sql" -l searchpattern 
Смежные вопросы