📄 grep.m
字号:
function [grepped] = grep(togrep, varargin)
% grep - GNU utils like grep
%
% FORMAT: grepped = grep(togrep, params, pattern, ...)
%
% Input fields:
%
% togrep either a filename, a text file contents, or a list
% (cell array) of strings
% params list of options (must be preceded by '-')
% multiple options can be mixed by adding them to the
% params argument, e.g. '-inr', available options are:
% 'aN' - match N lines after match
% 'bN' - match N lines before match
% 'hN' - only consider first N lines of input
% 'HN' - only return first N lines of output
% 'i' - ignore case
% 'l' - return line numbers instead of contents
% 'n' - enumerate (prepend line number to strings)
% 'tN' - only consider last N lines of input
% 'TN' - only return last N lines of output
% 'v' - inverse match
% 'x' - use regexp instead of strfind
% '[STRING]' - tag the output lines with STRING
% pattern one or more patterns given to match input with
%
% Output fields:
%
% grepped list of strings or line numbers with matched lines
%
% See also strfind, strmatch, regexp.
% Version: v0.5c
% Build: 6120415
% Date: Dec-04 2006, 3:15 PM CET
% Author: Jochen Weber, Brain Innovation, B.V., Maastricht, NL
% URL/Info: http://wiki.brainvoyager.com/BVQXtools
% enough arguments ?
if nargin < 2
error( ...
'BVQXtools:TooFewArguments',...
'Too few arguments. Try ''help %s''.',...
mfilename ...
);
end
% first option MUST be char
if ~ischar(varargin{1})
error( ...
'BVQXtools:BadArgument',...
'Bad params argument' ...
);
end
% get option content right
firstarg = varargin{1}(:)';
if ~isempty(firstarg) && ...
firstarg(1) == '-'
opts = firstarg(2:end);
patterns = {varargin{2:end}};
else
opts = '';
patterns = varargin;
end
pats = length(patterns);
for pat = 1:pats
patterns{pat} = patterns{pat}(:)';
end
% char content
if ischar(togrep)
ichar = 1;
togrep = togrep(:)';
% filename
if ~isempty(togrep) && ...
length(togrep) < 256 && ...
exist(togrep, 'file') == 2
togrep = asciiread(togrep);
end
% split according to line delim
if ~isempty(strfind(togrep, char([13, 10])))
[togrep, lines] = splittocell(togrep, char([13, 10]), 0, 0);
else
[togrep, lines] = splittocell(togrep, char(10), 0, 0);
end
% cell array already
elseif iscell(togrep)
ichar = 0;
lines = numel(togrep);
% check line content
for line = 1:lines
% only allow chars
if ~ischar(togrep{line})
error( ...
'BVQXtools:BadArgument',...
'Bad cell input for grep.' ...
);
else
togrep{line} = togrep{line}(:)';
end
end
% other content
else
error( ...
'BVQXtools:BadArgument',...
'Bad togrep argument.' ....
);
end
% check option: [tag]
tagname = '';
if any(opts == '[') && ...
any(opts == ']')
opos = find(opts == '[');
opos2 = find(opts == ']');
if opos(1) < opos2(1)
tagname = opts(opos(1)+1:opos2(1)-1);
opts = strrep(opts, ['[' tagname ']'],'');
tagname = [tagname ', '];
end
end
% check option: a(fter)
doafter = 0;
if any(opts == 'a')
opos = find(opts == 'a');
if opos(1) < length(opts)
opos = opts(opos(1)+1:end);
oposa = find(opos < 48 | opos > 57);
if isempty(oposa)
doafter = str2double(opos);
elseif oposa(1) > 1
doafter = str2double(opos(1:oposa(1)-1));
end
end
end
% check option: b(efore)
dobefore = 0;
if any(opts == 'b')
opos = find(opts == 'b');
if opos(1) < length(opts)
opos = opts(opos(1)+1:end);
oposa = find(opos < 48 | opos > 57);
if isempty(oposa)
dobefore = str2double(opos);
elseif oposa(1) > 1
dobefore = str2double(opos(1:oposa(1)-1));
end
end
end
% check option: h(ead before grep)
dohead = -1;
if any(opts == 'h')
opos = find(opts == 'h');
if opos(1) < length(opts)
opos = opts(opos(1)+1:end);
oposa = find(opos < 48 | opos > 57);
if isempty(oposa)
dohead = str2double(opos);
elseif oposa(1) > 1
dohead = str2double(opos(1:oposa(1)-1));
end
end
end
% check option: H(ead after grep)
doheada = -1;
if any(opts == 'H')
opos = find(opts == 'H');
if opos(1) < length(opts)
opos = opts(opos(1)+1:end);
oposa = find(opos < 48 | opos > 57);
if isempty(oposa)
doheada = str2double(opos);
elseif oposa(1) > 1
doheada = str2double(opos(1:oposa(1)-1));
end
end
end
% check option: t(ail before grep)
dotail = -1;
if any(opts == 't')
opos = find(opts == 't');
if opos(1) < length(opts)
opos = opts(opos(1)+1:end);
oposa = find(opos < 48 | opos > 57);
if isempty(oposa)
dotail = str2double(opos);
elseif oposa(1) > 1
dotail = str2double(opos(1:oposa(1)-1));
end
end
end
% check option: T(ail after grep)
dotaila = -1;
if any(opts == 'T')
opos = find(opts == 'T');
if opos(1) < length(opts)
opos = opts(opos(1)+1:end);
oposa = find(opos < 48 | opos > 57);
if isempty(oposa)
dotaila = str2double(opos);
elseif oposa(1) > 1
dotaila = str2double(opos(1:oposa(1)-1));
end
end
end
% check other options: case insensity, lines, enumberation
% and between options, reverse logic, regexp pattern match
if any(opts == 'i')
dolower = 1;
else
dolower = 0;
end
if any(opts == 'l')
dolines = 0;
else
dolines = 1;
end
if any(opts == 'n')
doenum = 1;
else
doenum = 0;
end
if any(opts == 'r')
doand = 0;
else
doand = 1;
end
if any(opts == 'v')
doreverse = 1;
else
doreverse = 0;
end
if any(opts == 'x')
doregexp = 1;
else
doregexp = 0;
end
% calculate complex option value
opts = 4 * doregexp + 2 * dolower + doreverse;
% preset output
mlines = [];
% lower patterns?
if dolower
for pat = 1:pats
patterns{pat} = lower(patterns{pat});
end
end
% heading and/or tailing before grepping
if dohead > -1
togrep = togrep(1:min(lines,dohead));
lines = length(togrep);
end
if dotail > -1
togrep = togrep((lines+1)-min(lines,dotail):lines);
lines = length(togrep);
end
% iterate over lines
for line=1:lines
% ANDing patterns
if doand
% default 1
match = 1;
% which complex option
% then check pattern and say no match if any failes
switch (opts), case {0}
for pat = 1:pats
if isempty(strfind(togrep{line}, patterns{pat}))
match = 0;
break;
end
end
case {1}
for pat = 1:pats
if ~isempty(strfind(togrep{line}, patterns{pat}))
match = 0;
break;
end
end
case {2}
for pat = 1:pats
if isempty(strfind(lower(togrep{line}), patterns{pat}))
match = 0;
break;
end
end
case {3}
for pat = 1:pats
if ~isempty(strfind(lower(togrep{line}), patterns{pat}))
match = 0;
break;
end
end
case {4}
for pat = 1:pats
if isempty(regexp(togrep{line}, patterns{pat}, 'once'))
match = 0;
break;
end
end
case {5}
for pat = 1:pats
if ~isempty(regexp(togrep{line}, patterns{pat}, 'once'))
match = 0;
break;
end
end
case {6}
for pat = 1:pats
if isempty(regexpi(togrep{line}, patterns{pat}, 'once'))
match = 0;
break;
end
end
case {7}
for pat = 1:pats
if ~isempty(regexpi(togrep{line}, patterns{pat}, 'once'))
match = 0;
break;
end
end
end
% ORing patterns
else
% default 0
match = 0;
% which complex option
% then check pattern and say match if any is true
switch (opts), case {0}
for pat = 1:pats
if ~isempty(strfind(togrep{line}, patterns{pat}))
match=1;
break;
end
end
case {1}
for pat = 1:pats
if isempty(strfind(togrep{line}, patterns{pat}))
match=1;
break;
end
end
case {2}
for pat = 1:pats
if ~isempty(strfind(lower(togrep{line}), patterns{pat}))
match=1;
break;
end
end
case {3}
for pat = 1:pats
if isempty(strfind(lower(togrep{line}), patterns{pat}))
match=1;
break;
end
end
case {4}
for pat = 1:pats
if ~isempty(regexp(togrep{line}, patterns{pat}, 'once'))
match=1;
break;
end
end
case {5}
for pat = 1:pats
if isempty(regexp(togrep{line}, patterns{pat}, 'once'))
match=1;
break;
end
end
case {6}
for pat = 1:pats
if ~isempty(regexpi(togrep{line}, patterns{pat}, 'once'))
match=1;
break;
end
end
case {7}
for pat = 1:pats
if isempty(regexpi(togrep{line}, patterns{pat}, 'once'))
match=1;
break;
end
end
end
end
% match found
if match
mlines(end+1) = line;
if dobefore > 0
mlines = union(mlines, max(1,line - dobefore):(line - 1));
end
if doafter > 0
mlines = union(mlines, (line + 1):min(lines, line + doafter));
end
end
end
% line enumberation
if dolines
if doenum
for ml = mlines
togrep{ml} = sprintf('%s%d: %s', tagname, ml, togrep{ml});
end
end
grepped = togrep(mlines);
else
grepped = mlines;
return;
end
% head or tail after grepping
if doheada > -1
lines = length(grepped);
grepped = grepped(1:min(lines,doheada));
end
if dotaila > -1
lines = length(grepped);
grepped = grepped((lines + 1) - min(lines, dotaila):lines);
end
% result as char
if ichar
grepped = gluetostring(grepped);
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -