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 ;
тогда вы должны получить только тот файл, который имеет то, что вы ищете.