【问题标题】:Filter data based on matches within data根据数据中的匹配过滤数据
【发布时间】:2014-03-04 20:47:51
【问题描述】:

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

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

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

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

预期输出:

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

【问题讨论】:

  • 如果您正在处理一个文件,为什么要将此标记为“sql”?
  • 文件是否可以包含除点和星之外的任何正则表达式字符(即:.*)?
  • @GordonLinoff 可以使用 SQL 导入和查询文件。我不想将其限制为命令行工具。
  • @HåkonHægland * 是字符串 (abc.def.ghi*) 中唯一应被视为正则表达式字符的字符。
  • 一行是否只有一个星号,如果是:它是该行的最后一个字符吗?

标签: sql sed filter awk


【解决方案1】:

您可以在 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
                 );

【讨论】:

    【解决方案2】:
    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 个 -

    【讨论】:

      【解决方案3】:

      使用 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 \* 使用 * 作为字段分割
      • if (/\*/)a[$1] 将带有 * 的行的 $1 保存到数组 a 中,所以得到两个:A, abcB, cde.def.
      • NR&gt;FNR中的下一部分,再次读取文件,如果该行有*,直接打印。如果不是,则计算当前行是否匹配A, abcB, cde.def.。如果 finally s 仍然为 0,则表示不匹配,打印,否则,跳过。

      【讨论】:

      • 很好.. 但是假设星号是行中的最后一个字符,并且i.. 中没有正则表达式字符。
      • 我没有投票给你..我通常不会拒绝任何答案..这只是一个评论..我认为你在这里(在 SE)有很多很好的答案..跨度>
      猜你喜欢
      • 1970-01-01
      • 2020-07-30
      • 1970-01-01
      • 2017-12-23
      • 1970-01-01
      • 1970-01-01
      • 2021-02-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多