grep - распознавать возврат каретки как новую строку

Я хочу найти на веб-сервере, работающем под Unix, php-файлы, содержащие определенную строку. Обычно я использую эти команды для достижения этой цели:

find . -name "*.php" -print0 | xargs -0 grep -H -i "the string to search for"

Он найдет любой php-файл, содержащий "строку для поиска", и напечатает имя файла и строку, в которой было найдено совпадение.

До сих пор это прекрасно работало, но теперь я столкнулся с сервером, на котором все php-скрипты не имеют перевода строки, а вместо этого возвращаются только каретки. Похоже, что grep не распознает возврат каретки как новую строку, поэтому приведенная выше команда напечатает все содержимое файла, если в нем есть совпадение, а не просто напечатает строку.

Любая помощь будет принята с благодарностью!

3 ответа

К сожалению, grep не будет делать то, что вы хотите. Нет опции командной строки, чтобы заставить его распознавать символ CR как разделитель строк. Тем не менее, вы можете делать что хотите с небольшим количеством awk! Попробуй это:

find . -name '*.php' -print0 | \
    xargs -0 awk -v RS="\r" '/string to search for/ {print FILENAME ": " $0}'

Awk не так быстр, как grep, поэтому этот метод может занять гораздо больше времени в зависимости от количества файлов и их размеров. Может быть, стоит просто преобразовать все окончания строк в ваших PHP-файлах, если вы собираетесь много разбираться с ними. Если у вас нет удобной утилиты, которая могла бы сделать это для вас, этот сценарий оболочки должен сделать это:

find . -name '*.php' | while read PHPFILE; do
    mv "$PHPFILE" "$PHPFILE".orig
    awk -v RS="\r" '{print $0}' < "$PHPFILE".orig > "$PHPFILE"
done

Как насчет использования (grep на моей Ubuntu, почти уверен, что у большинства grep есть этот флаг)

  -o, --only-matching
         Print only the matched (non-empty) parts of a matching line, with each such >part on a separate output line.

вместе с

  -b, --byte-offset
         Print  the  0-based byte offset within the input file before each line of >output.  If -o (--only-matching) is specified, print the offset of
         the matching part itself.

Тогда у вас есть имя файла и часть, которую вы хотите.

Кроме того, как вам удалось так манипулировать вашими файлами? Я пытался использовать VI, чтобы заменить символы новой строки только CR. Но это заставило grep и cat вести себя очень странно.

содержимое файла test

gggggggggggggggggggg ^ Mggggggggasdfgggggggg ^ Mgggggggggggggggggggg

~ / test $ grep asdf test

gggggggggggggggggggg

~ / test $ cat test

gggggggggggggggggggg

Выглядит нормально в блокноте

Что делать, если вы делаете что-то подобное?

for i in `find . -name "*.php" -print` ; do grep -H -i "the string to search for" $i 2>/dev/null >/dev/null ; if [ $? -eq 0 ] ; then echo $i ; fi ;  done ;

тогда вы должны получить только тот файл, который имеет то, что вы ищете.

Другие вопросы по тегам