2011-01-26 71 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