Назад | Перейти на главную страницу

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

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

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

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

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

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

К сожалению, 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 тест

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 ;

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