根据数据内的匹配过滤数据

时间:2014-02-07 12:26:34

标签: sql sed filter awk

逗号分隔文件包含两列,包含两个字符串。

A, abc*
A, abc.def.ghi
A, abc.def.ghi.jkhl
B, abc.def.gh
B, cde.def.abc
B, cde.def.*

char *是一个匹配零或更多的通配符。

删除reduntant行的最简单方法是什么,即匹配任何通配符行? 最好使用Unix过滤器或SQL,但任何非gui解决方案都是有帮助的。

预期产出:

A, abc*
B, abc.def.gh
B, cde.def.*

3 个答案:

答案 0 :(得分:0)

您可以在SQL中执行此操作:

select t.*
from table t
where not exists (select 1
                  from table t2
                  where t.col1 = t2.col1 and
                        t.col2 like replace(t2.col2, '*', '%') and
                        t.col2 <> t2.col2
                 );

答案 1 :(得分:0)

sort YourFile | sed '#n
H
$ {s/.*//;H;x
: again
   s/\(\n\)\([^*[:cntrl:]]\{1,\}\)[*][^[:cntrl:]]*\(.*\)\n\2[^[:cntrl:]]*\n/\1\2*\3\1/
   t again
   s/^\n\(.*\)\n[[:blank:]]*$/\1/
   p
   }'
使用

sort因为它比在sed中更快并且简化了测试内容的顺序(带有*的字符串总是在其他字母开始相同的模式之前)。

普林西: 找到在\n之后开始并以*之后的某个地方结束的任何模式,如果是这种情况,则将找到的行替换为空并重试(t again)。 [:cntrl:]用于捕获posix sed中无法捕获的\ n。

使用GNU sed添加--posix选项(可能是1 -

答案 2 :(得分:-1)

使用awk

awk -F \* 'NR==FNR{if (/\*/)a[$1]}
NR>FNR{  if (/\*/)
       {print;next}
   s=0
   for (i in a)
       {if ($0~i){s++;break}}
   if (s==0) print
}' file file

解释

  • -F \*使用*作为Field-Splitting
  • if (/\*/)a[$1]将带有*的$ 1行保存到数组a中,所以得到两个:A, abcB, cde.def.
  • NR>FNR中的下一部分,再次读取该文件,如果该行有*,则直接打印。如果不是,请计算当前行是否与A, abcB, cde.def.匹配。如果最后s仍为0,则表示不匹配,打印,否则,跳过。