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