2008-10-21 3 views
2

В настоящее время я использую следующую команду, но она немного громоздка для ввода. Что представляет собой более короткую альтернативу?Что представляет собой более сжатый способ поиска текста в наборе файлов?

find . -name '*.txt' -exec grep 'sometext' '{}' \; -print 

Вот мои требования:

  • ограничение на расширение файла (я использую SVN и не хочу, чтобы поиск по всему этим папкам .svn)
  • может по умолчанию тока каталог, но это хорошо, чтобы иметь возможность указать другой каталог
  • должен быть рекурсивными

UPDATE: Вот мое лучшее решение до сих пор:

grep -r 'sometext' * --include='*.txt' 

UPDATE # 2: После использования Grep немного, я понял, что мне нравится выход моего первого метода лучше. Итак, я следил за предложениями нескольких респондентов и просто сделал сценарий оболочки, и теперь я называю это двумя параметрами (расширение и текст для поиска).

ответ

9

grep имеет -r (рекурсивно) и --include (для поиска только в файлах и каталогах, соответствующих шаблону).

+1

Стоит отметить, что эти параметры не переносятся через унификации. – 2008-10-21 18:11:27

3

Если это слишком нерешительно, напишите сценарий, который это сделает, и поместите в свой личный каталог bin. У меня есть «РИФ» скрипт, который ищет исходные файлы для текста, в основном просто делает один найти, как вы здесь:

#!/bin/bash 

set -f # disable pathname expansion 

pattern="-iname *.[chsyl] -o -iname *.[ch]pp -o -iname *.hh -o -iname *.cc 
-o -iname *.java -o -iname *.inl" 
prune="" 
moreargs=true 
while $moreargs && [ $# -gt 0 ]; do 
    case $1 in 
    -h) 
     pattern="-iname *.h -o -iname *.hpp -o -iname *.hh" 
     shift 
     ;; 
    -prune) 
     prune="-name $2 -prune -false -o $prune" 
     shift 
     shift 
     ;; 
    *) 
     moreargs=false; 
     ;; 
    esac 
done 

find . $prune $pattern | sed 's/ /\\ /g' | xargs grep "[email protected]" 

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

1

Вы можете написать сценарий (в bash или что-то еще - у меня есть один в Groovy) и поместить его на путь. Например.

$ myFind.sh txt targetString 

где myFind.sh является:

find . -name "*.$1" -exec grep $2 {} \; -print 
0

Я избежать обычно работают на жидком "человек найти", используя grep $(find . -name "*,txt")

2

я использую ЗШ, который имеет рекурсивную подстановку. Если вам нужно смотреть на конкретных типах файлов, следующий будет эквивалентны ваш пример:

grep 'sometext' **/*.txt 

Если вы не заботитесь о типах файлов, опция -r будет лучше:

grep -r 'sometext' * 

Хотя Минорное твик к исходному примеру даст вам именно то, что вы хотите:

find . -name '*.txt' \! -wholename '*/.svn/*' -exec grep 'sometext' '{}' \; -print 

Если это то, что вы делаете часто, делают его функцию (поставить это в вашей конфигурации оболочки):

function grep_no_svn { 
    find . -name "${2:-*}" \! -wholename '*/.svn/*' -exec grep "$1" '{}' \; -print 
} 

Если первый аргумент функции - это текст, который вы ищете.Итак:

$ grep_here_no_svn "sometext" 

Или:

$ grep_here_no_svn "sometext" "*.txt" 
+0

После того, как список файлов будет слишком длинным, глобализация будет ограничена размером командной строки. Сочетания find и xargs не будут иметь этой проблемы. – 2008-10-27 00:23:01

3

Это гораздо более эффективно, так как он вызывает grep гораздо меньше времени, хотя это трудно сказать, что это более лаконичным:

find . -name '*.txt' -print0 | xargs -0 grep 'sometext' /dev/null 

Примечания:

/find -print0 и xargs -0 содержит пути с встроенные заготовки работают правильно.

Аргумент /dev/null гарантирует, что grep всегда добавляет имя файла.

+0

Как насчет `-H` (` --with-filename`) вместо этого обходного пути? – ephemient 2008-10-21 20:18:57

+0

`find. -name '* .txt' -exec grep 'sometext'/dev/null {} + `будет более кратким и эффективным способом сделать это. – 2012-12-29 03:06:12

3

ack Установка и использование

ack -aG'\.txt$' 'sometext' 
+0

Это решение является наиболее кратким, но, к сожалению, требует установки ack и даже менее портативна, чем прямая команда find или grep. – jgormley 2008-10-22 02:57:22

3

I предложение второго ephemient в АСК. Я пишу этот пост, чтобы выделить конкретную проблему.

В ответ на jgormley (в комментариях): ack доступен как один файл, который будет работать везде, где установлена ​​правильная версия Perl (что есть везде).

Учитывая, что на платформах, отличных от Linux grep регулярно не принимает -R, возможно, с помощью ackявляется более портативный.

0

Вы говорите, что вам нравится результат вашего метода (с помощью find). Единственное различие, которое я вижу между ними, заключается в том, что grepping несколько файлов будут помещать имя файла на передний план.

Вы всегда можете (в GNU grep, но вы должны использовать это или -r и --include не работает) отключите имя файла, используя -h (--no-filename). Напротив, для тех, кто хочет имена файлов, но должен использовать find по какой-либо другой причине, есть -H (--with-filename).