Читая, я предполагаю, что мы не можем использовать gnu coreutil , и egrep недоступен.Я предполагаю (по какой-то причине), что система сломана, и выходы не работают должным образом.
В обычных ситуациях grep -rf patternfile.txt /some/dir/
- это путь.
файлсодержащий список всех строк для поиска
Допущения: gnu coreutil недоступен.grep -r не работает.обработка специального символа нарушена.
Теперь у вас работает awk?нет?Это делает жизнь намного проще.Но давайте будем в безопасности.
Предположим: работает sed
, доступен один из od
ИЛИ hexdump
ИЛИ xxd
(из пакета vim).
Позволяет вызывать этот patternfile.txt
1.Преобразуйте список в регулярное выражение, которое grep любит
Пример patternfile.txt содержит
/ foo /
/ bar / doe /
/ root/
(пример не печатает специальный символ, но он есть). Мы должны превратить его в нечто вроде
(/foo/|/bar/doe/|/root/)
Предполагая команду echo -en
не сломан, и xxd
, или od
, или hexdump
доступны,
Используя hexdump
cat patternfile.txt |hexdump -ve '1/1 "%02x \n"' |tr -d '\n'
Используя od
cat patternfile.txt |od -A none -t x1|tr -d '\n'
и передать его в канал (общий для hexdump и od) |sed 's:[ ]*0a[ ]*$::g'|sed 's: 0a:\\|:g' |sed 's:^[ ]*::g'|sed 's:^: :g' |sed 's: :\\x:g'
, затем передать результат в |sed 's:^:\\(:g' |sed 's:$:\\):g'
, и у вас есть шаблон регулярного выражения, который экранируется.
2.Заполните экранированный шаблон в неработающее регулярное выражение
Предполагая, что минимальный выход оболочки возможен, мы используем grep "$(echo -en "ESCAPED_PATTERN" )"
для нашей работы.
3.Подводя итог:
Построение экранированного шаблона регулярного выражения (на примере hexdump)
grep "$(echo -en "$( cat patternfile.txt |hexdump -ve '1/1 "%02x \n"' |tr -d '\n' |sed 's:[ ]*0a[ ]*$::g'|sed 's: 0a:\\|:g' |sed 's:^[ ]*::g'|sed 's:^: :g' |sed 's: :\\x:g'|sed 's:^:\\(:g' |sed 's:$:\\):g')")"
будет экранировать все символы и заключать его в(|) в скобках, поэтому будет выполнено регулярное выражение ИЛИ.
4.Рекурсивный поиск в каталогах
В нормальных ситуациях, даже если grep -r
не работает, find /dir/ -exec grep {} \;
должен работать.Некоторые могут предпочесть xargs
instaed (если только у вас не было глючных xargs).Мы предпочитаем find /somedir/ -type f -print0 |xargs -0 grep -f 'patternfile.txt'
подход, но так как он недоступен (по какой-либо уважительной причине), нам нужно выполнить grep
для каждого файла, и это обычно неправильный путь.Но давайте сделаем это.
Предположим: find -type f
работает.Предположим: xargs
сломан ИЛИ не доступен.
Во-первых, если у вас глючный канал, он может не обрабатывать большое количество файлов.Поэтому мы избегаем xargs
в таких системах (я знаю, я знаю, просто давайте притворимся, что он сломан).
find /whatever/dir/to/start/looking/ -type f > list-of-all-file-to-search-for.txt
ЕСЛИ ваша оболочка прекрасно обрабатывает списки больших размеров, for file in cat list-of-all-file-to-search-for.txt ; do grep REGEXP_PATTERN "$file" ;
done ;
это хороший способ обойтись.К сожалению, некоторым системам это не нравится, и в этом случае вам может потребоваться cat list-of-all-file-to-search-for.txt | split --help -a 4 -d -l 2000 file-smaller-chunk.part.
, чтобы превратить его в более мелкие куски.Теперь это для серьезно сломанной системы.тогда for file in file-smaller-chunk.part.* ; do for single_line in cat "$file" ; do grep REGEXP_PATTERN "$single_line" ; done ; done ;
должен работать.
A cat filelist.txt |while read file ; do grep REGEXP_PATTERN $file ; done ;
может использоваться в качестве обходного пути на некоторых системах.
Что если моя оболочка не обрабатывает кавычки?
Вы можетенеобходимо предварительно покинуть список файлов.
Это может быть сделано намного лучше в awk
, perl
, что угодно, но поскольку мы ограничиваем себя sed
, давайте сделаем это.Мы предполагаем, что 0x27, the ' code
действительно будет работать.cat list-of-all-file-to-search-for.txt |sed 's@['\'']@'\''\\'\'\''@g'|sed 's:^:'\'':g'|sed 's:$:'\'':g'
Единственный раз, когда мне пришлось использовать это, было при подаче вывода в bash снова.
Что, если моя оболочка не справится с этим?
xargs
завершится неудачей, grep -r
завершится неудачей,Оболочка для цикла завершается неудачей.
Есть ли у нас другие вещи?ДА.
Избегайте ввода, подходящего для вашей оболочки, и создайте сценарий.
Но вы знаете, что у меня есть доска, и написание автоматических сценариев для csh кажется неправильным.Поэтому я остановлюсь здесь.
Возьмите домашнюю заметку
Используйте инструмент для правильной работы.Написание интерпретатора на bc
вполне возможно, но это просто неправильно.Установите coreutils, perl
, лучше grep
, чем когда-либо.делает жизнь лучше.