[英]How to match once per file in grep?
是否有任何grep選項讓我控制匹配的總數但在每個文件的第一次匹配時停止?
例:
如果我這樣做grep -ri --include '*.coffee' 're' .
我明白了:
./app.coffee:express = require 'express'
./app.coffee:passport = require 'passport'
./app.coffee:BrowserIDStrategy = require('passport-browserid').Strategy
./app.coffee:app = express()
./config.coffee: session_secret: 'nyan cat'
如果我做grep -ri -m2 --include '*.coffee' 're' .
,我明白了:
./app.coffee:config = require './config'
./app.coffee:passport = require 'passport'
但是,我真正想要的是這個輸出:
./app.coffee:express = require 'express'
./config.coffee: session_secret: 'nyan cat'
做-m1
不起作用,因為我得到這個grep -ri -m1 --include '*.coffee' 're' .
./app.coffee:express = require 'express'
嘗試不使用grep例如這個find . -name '*.coffee' -exec awk '/re/ {print;exit}' {} \\;
find . -name '*.coffee' -exec awk '/re/ {print;exit}' {} \\;
制作:
config = require './config'
session_secret: 'nyan cat'
更新:如下所述,GNU grep -m
選項處理每個文件的計數,而-m
表示BSD grep將其視為全局匹配計數
因此,使用grep
,您只需要選項-l, --files-with-matches
。
關於find
, awk
或shell腳本的所有答案都遠離問題。
我想你可以做點什么
grep -ri -m1 --include '*.coffee' 're' . | head -n 2
例如,從每個文件中選擇第一個匹配,並且最多選擇兩個匹配。
請注意,這需要您的grep
將-m
視為每個文件的匹配限制; GNU grep
會這樣做,但BSD grep
顯然將其視為全局匹配限制。
我會用awk
來做這件事。
find . -name \*.coffee -exec awk '/re/ {print FILENAME ":" $0;exit}' {} \;
如果你不需要遞歸,你可以用awk來做:
awk '/re/ {print FILENAME ":" $0;nextfile}' *.coffee
或者,如果你使用足夠的當前bash,你可以使用globstar:
shopt -s globstar
awk '/re/ {print FILENAME ":" $0;nextfile}' **/*.coffee
使用find和xargs。 找到每個.coffee文件並為每個文件執行excute -m1 grep
find . -print0 -name '*.coffee'|xargs -0 grep -m1 -ri 're'
沒有-m1的測試
linux# find . -name '*.txt'|xargs grep -ri 'oyss'
./test1.txt:oyss
./test1.txt:oyss1
./test1.txt:oyss2
./test2.txt:oyss1
./test2.txt:oyss2
./test2.txt:oyss3
添加-m1
linux# find . -name '*.txt'|xargs grep -m1 -ri 'oyss'
./test1.txt:oyss
./test2.txt:oyss1
find . -name \\*.coffee -exec grep -m1 -i 're' {} \\;
find的-exec選項為每個匹配的文件運行一次命令(除非你使用+
而不是\\;
;,這使它像xargs一樣)。
你可以在perl中輕松完成這個任務,而且不會出現凌亂的跨平台問題!
use strict;
use warnings;
use autodie;
my $match = shift;
# Compile the match so it will run faster
my $match_re = qr{$match};
FILES: for my $file (@ARGV) {
open my $fh, "<", $file;
FILE: while(my $line = <$fh>) {
chomp $line;
if( $line =~ $match_re ) {
print "$file: $line\n";
last FILE;
}
}
}
唯一的區別是你必須使用Perl樣式的正則表達式而不是GNU樣式。 他們並沒有太大的不同 。
您可以使用File :: Find在Perl中執行遞歸部分,或使用find
feed it files。
find /some/path -name '*.coffee' -print0 | xargs -0 perl /path/to/your/program
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.