2011-01-26 77 views
3

我做了线条简单的grep开始像一些格局研究:grep的重定向不匹配

grep -E "^AAA" myfile > newfile 

我想也(在同一GO)重定向那些不匹配的行另一个文件。
我知道这将是可以简单地做两次,并在第二次尝试使用-v,但文件是(相对)巨大的,只有在阅读他们一次会节省一些很宝贵的时间......

我正沿着重定向不匹配的思路东西到stderr,如:

grep -E -magic_switch "^AAA" myfile > newfile 2> newfile.nonmatch 

是这一招在某种程度上可能与grep的还是应该我宁愿只是代码呢?

(可能是额外的价值 - 我在bash脚本编码本)

回答

4

这将活像K:

awk '/pattern/ {print; next} {print > "/dev/stderr"}' inputfile 

awk -v matchfile=/path/to/file1 -v nomatchfile=/path/to/file2 '/pattern/ {print > matchfile; next} {print > nomatchfile}' inputfile 

#!/usr/bin/awk -f 
BEGIN { 
    pattern  = ARGV[1] 
    matchfile = ARGV[2] 
    nomatchfile = ARGV[3] 
    for (i=1; i<=3; i++) delete ARGV[i] 
} 

$0 ~ pattern { 
    print > matchfile 
    next 
} 

{ 
    print > nomatchfile 
} 

调用最后一个是这样的:

./script.awk regex outputfile1 outputfile2 inputfile 
+0

不错!我总是喜欢使用标准工具来编写代码,而单行则值得加分;) – nEJC 2011-01-26 23:11:49

2

我担心这可能是不可能的。我会用Perl和做类似:

if (/^AAA/) { 
    print STDOUT $_; 
} 
else 
{ 
    print STDERR $_; 
} 
+1

Downvoted为什么呢? – 2015-05-14 08:11:43

2

我不相信这可以用grep做,但它的Perl的只有几行:

#! /usr/bin/perl 
# usage: script regexp match_file nomatch_file < input 

my $regexp = shift; 
open(MATCH, ">".shift); 
open(NOMATCH, ">".shift); 

while(<STDIN>) { 
    if (/$regexp/o) { 
     print MATCH $_; 
    } else { 
     print NOMATCH $_; 
    } 
} 

或Python,如果你喜欢:

#! /usr/bin/python 
# usage: script regexp match_file nomatch_file < input 

import sys 
import re 

exp = re.compile(sys.argv[1]) 
match = open(sys.argv[2], "w") 
nomatch = open(sys.argv[3], "w") 

for line in sys.stdin: 
    if exp.match(line): match.write(line) 
    else:    nomatch.write(line) 

(两者没有经过测试您的里程可能会有所不同禁止地区无效。)

+0

happythankyouverymuch!我只需要py代码...你只需5分钟就可以浏览参考文件;) – nEJC 2011-01-26 17:07:33

0

这是给你的函数:

function perg { 
    awk '{y = $0~z ? "out" : "err"; print > "/dev/std" y}' z="$1" "$2" 
} 

使用它与文件

perg ^AAA myfile > newfile 2> newfile.nonmatch 

或从管道

cat myfile | perg ^AAA > newfile 2> newfile.nonmatch 
0

您可以使用进程替换复制管道作为文件被读取(灵感https://unix.stackexchange.com/a/71511)。这应该几乎与性能一样,因为该文件仍然只被读取一次。

像这样的东西应该工作:

cat file.txt | tee >(grep 'pattern' > matches.txt) | grep -v 'pattern' > non-matches.txt