我想在运行 unix 的 Web 服务器上搜索包含特定字符串的 php 文件。通常我使用以下命令来实现此目的:
find . -name "*.php" -print0 | xargs -0 grep -H -i "the string to search for"
这将找到任何包含“要搜索的字符串”的 php 文件,并打印文件名和匹配的行。
到目前为止,这一直很有效,但现在我遇到了一个服务器,其中所有的 php 脚本都没有任何换行符,而只有回车符。grep 似乎不能将回车符识别为换行符,因此上面的命令将打印文件的全部内容(如果文件中有匹配项),而不仅仅是打印该行。
任何帮助将不胜感激!
答案1
那么使用怎么样(在我的 Ubuntu 上使用 grep,很确定大多数 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 的行为非常奇怪。
文件测试的内容
gggggggggggggggggggg^Mggggggggasdfgggggggg^Mggggggggggggggggggggggg
~/测试$ grep asdf 测试
gggggggggggggggggggg
~/test$ cat 测试
gggggggggggggggggggg
在记事本中看起来正常
答案2
不幸的是,grep 不会按照你的要求执行。没有命令行选项可以让它将 CR 字符识别为行分隔符。但是,你可以使用 awk 来做你想做的事情!试试这个:
find . -name '*.php' -print0 | \
xargs -0 awk -v RS="\r" '/string to search for/ {print FILENAME ": " $0}'
Awk 的速度远不如 grep,因此此方法可能需要更长的时间,具体取决于文件的数量及其大小。如果您要对 PHP 文件进行大量 grep,则可能值得简单地转换所有行尾。如果您没有方便的实用程序可以为您执行此操作,则此 shell 脚本应该可以做到:
find . -name '*.php' | while read PHPFILE; do
mv "$PHPFILE" "$PHPFILE".orig
awk -v RS="\r" '{print $0}' < "$PHPFILE".orig > "$PHPFILE"
done
答案3
如果你做了这样的事会怎么样?
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 ;
那么您应该只会获得包含您正在寻找的内容的文件的输出。