我是 Windows 生態系統的新手。我的任務是編寫一個程序,在數千個檔案中搜尋數十個(甚至數百個)特定字串。需要匹配的字串是僅由數字和字母組成的序號,且長度小於20個字元。現在,我的程式正在執行以下命令:
findstr /i /m /s "searchStr" "C:\Directory\To\Search\*.*"
上面的指令可以工作,但是速度太慢。可能包含特定序號的檔案將僅在其第一行包含序號。
有誰知道一種有效的方法來遞歸搜尋目錄中僅在第一行包含特定字串的所有檔案?
答案1
在 PowerShell (v3.0+) 中,也許...
Get-ChildItem -Path x:\pathto\*.log `
| ForEach-Object {
if (Get-Content -LiteralPath $_ -First 1 `
| Select-String -SimpleMatch -Pattern 'serialnumber')
{
Write-Output $_
}
}
不同的參數可以Get-ChildItem
遞歸子資料夾等;可以Get-Content
從文件中獲取更多或更少的內容; toSelect-String
可以執行更複雜的匹配(正規表示式、區分大小寫等)。
答案2
如果您不需要使用,我可以建議一些選項findstr
,但首先您應該看看是否可以將搜尋限制為特定文件類型的文件,因為這肯定會加快速度。
文件定位器精簡版根據我的經驗,它可以更快地找到文件並檢查其內容。請務必填寫「檔案名稱」(如果適用)和「包含的文字」欄位以及起始目錄。
ag -il "searchStr"
:股份公司專為速度而設計,因此它應該能夠快速為您提供結果。如果可以的話,請務必按文件類型限制搜索,儘管預設情況下已經跳過二進位。也可在西格文。find -exec awk 'BEGIN {IGNORECASE=1} NR==1 && /searchStr/ {print FILENAME": "$0}' {} \;
如果您有 Cygwin 或其他類似 POSIX 的環境可用,請嘗試此操作,以檢查您關於僅搜尋第一行的想法。組合起來find
獲取檔案名稱(並希望也過濾它們)並awk
檢查第一行並將其與檔案名稱一起列印。find | parallel 'perl -lane '\'' print "$ARGV: $_" if $. == 1 and /searchStr/i '\'' {}'
嘗試加快速度的另一個想法是讓可用的核心和線程工作:這就是GNU並行是為了.這個例子是 sports ,但它的作用與上面perl
相同。這是命令細分:awk
3.
find
在目前目錄及其子目錄中尋找文件。您可以指定要尋找的不同目錄以及要篩選的檔案模式或副檔名:find /cygdrive/c/Directory/To/Search -iname "*.txt"
。|
“管道”,即將結果清單提供給下一個命令。parallel
並行執行下一個命令。perl
擅長文字檔案操作的腳本語言,可以替換sed
或awk
.-lane
一組有用的 perl 單行開關。'\''
轉義撇號,因為我們已經在 後打開了撇號集,所以需要轉義撇號parallel
。print "$ARGV: $_"
列印檔案名稱 ($ARGV
)、冒號、空格和整行 ($_
)。if
僅當滿足以下條件時才執行前一條指令。$. == 1
行號 ($.
) 等於一 (1
),也就是我們正在檢視文件的第一行。and
也必須滿足以下條件。/searchStr/i
正在檢查的行包含文本searchStr
,不區分大小寫。'\''
另一個轉義撇號標誌著指令的結束perl
。{}
這將被替換為parallel
傳遞的每個檔案名稱find
。'
指令結束parallel
。
更新:awk
即使操作僅綁定到第一行,也會perl
讀取整個檔案。解決方案是在第 2 行明確停止闡述:
find -exec awk 'BEGIN {IGNORECASE=1} NR > 1 {exit} /searchStr/ {print FILENAME": "$0}' {} \;
find | parallel 'perl -lape '\'' exit if $. == 2; print "$ARGV: $_" if /searchStr/i '\'' {}'