2016-07-20 102 views
3

是否有任何有用的命令組合(sed/grep/find等)我可以用它來檢測.php文件不以註釋開頭?我當然可以寫一個小腳本,但我寧願使用shell命令。遞歸找到所有不以評論開頭的php文件

匹配模式:

<?php 
/* 

我想在文件中的內容,而不是文件名搜索。

我必須處理一個被黑客入侵的網站,其中代碼注入遵循某種模式。

<?php $code.... 
/* 

<?php 
$code.... 
/* 
+0

[獲取靈感來源於此解決方案](http://stackoverflow.com/questions/21368838/how-do-i-find-all-files-that-do-not-begin-with-a-given-prefix在bash中),下次給我們更多的代碼。 – ODelibalta

+0

我**不**搜索文件名。而且我沒有更多的代碼可以提供,因爲我希望grep所有文件的模式是'<?php \ n/*' – christian

+0

如果您不搜索文件名,那麼您的預期輸出是什麼? – kenorb

回答

3

使用gnu grep您可以使用此遞歸搜索:

grep -rvlz $'^[[:space:]]*<?php\n/\*' --include='*.php' 
+0

我很喜歡這種方法,但它並沒有解決問題,因爲它會查詢整個文件,並且只返回不包含_any_註釋的文件。我只需要搜索前幾個字節。 – christian

+1

太棒了,正是我在找的東西。你能解釋一下'^ [[:space:]] *'-magic嗎? – christian

+0

這是用於匹配包括新行在內的任何空格的POSIX類屬性。 Anchor ^確保我們只在開始時匹配它。 – anubhava

1

這將檢測與一個PHP標籤開始的所有PHP文件;

find ./ -iname '*.php' | xargs head -v -n 1 | grep -B 1 '<?php' 
  • 查找所有文件與PHP擴展。
  • 第一行幷包含文件名。
  • grep這個輸出找到任何以php標籤開頭的文件。
  • -B 1:在比賽前保留1行,所以我們得到文件名。

這是快速和骯髒的,你可以想到使輸出更好或使其更加健壯。

0

從你可以使用這個小awk腳本,以找出是否該文件開始與評論外殼:

awk 'NR==2 && f$0!="<?php/*"{print FILENAME}NR>2{exit 1}{f=$0}' file.php 

要遞歸的使用腳本的目錄,使用:

find -name '*.php' \ 
    -exec awk 'NR==2 && f$0!="<?php/*"{print FILENAME}NR>2{exit 1}{f=$0}' {} \; 

可能的空間是對上述解決方案的限制,但可以通過在與<php?/*

比較之前刪除所有可能的空間
0

awk是你的朋友:

find /your/path/here -type f -iname "*.php" -exec \ 
awk 'FNR==2{if($0~/^\/\*/){print FILENAME};exit}' {} \; 

注意

  1. {}find傳遞給awk的說法。
  2. AWK內置FILENAME包含正在處理
  3. $0~/^\/\*/搜索/*在第二行
  4. FNR==2長相選擇的記錄數來處理的開始時的當前文件,exit用於處理所需要的記錄後退出的awk。
0

的UNIX工具來查找文件是很適當命名find和UNIX工具做通用的文本操作是awk

find . -name '*.php' -print | 
xargs awk -v RS='^$' 'index($0,"<?php\n/*")==1{print FILENAME}' 

以上使用GNU awk來實現多字符RS。我們使用index()來強制執行一個字符串而不是正則表達式搜索,因爲您的目標字符串包含多個正則表達式元字符,所以這可以節省我們全部逃脫它們。

+0

謝謝。 Awk對我來說總是一個謎,但是你的解決方案似乎並不完全工作。我不太確定這是否可能是由於不同類型的結局(\ r \ n vs \ n)。此外,我正在尋找文件**而不是匹配模式。 :) – christian

+0

是的,如果你的行結束符是'\ r \ n',那麼只需在腳本中將'\ n'改爲'\ r \ n',但不能這樣做,因爲你接受的解決方案假設爲'\ n'行結局。如果你想搜索那些不是以字符串開頭的文件,只需將'=='改爲'!='。 –