AWK解决方案否定CSV的模式

问题描述 投票:0回答:2

我有一个模式列表的文件,必须从CSV中删除与$ 5列完全/部分匹配(从$ 1开始计算)。

尝试过grep -vwF -f <pattern file> <csv file>

由于某种原因,它不起作用。我需要一个awk解决方案。

输入文件:

type|||URL|||Date|||Domain|||Referral URLs|||more columns
1|||https://www.google.com|||1524024000|||google.com|||https://www.google.com||| and more 
2|||www.bwin.hu|||1524024324|||bwin.hu|||http://www.bwin.hu/q=sdlfj||| and more

模式文件可能包含:bwin.huwww.bwin.huhttp://www.bwin.hu

需要输出:

1|||https://www.google.com|||1524024000|||google.com|||https://www.google.com||| and more 

旧帖不起作用的原因是列数更多。我省略它们的错误。

awk text-processing
2个回答
2
投票

不是很清楚,通过查看您的样品并尝试我可以写这个。您可以尝试一下(也仅使用您提供的样品进行测试)。

awk '
BEGIN{
  FS="\\|\\|\\|"
}
FNR==NR{
  a[$0]=$0
  next
}
{
  val=$2
}
{
  flag=""
  for(i in a){
      if(a[i] ~ val){
         flag=1
      }
  }
}
!flag
'  pattern_file  Input_file

几点需要注意:

1-为了更安全的一面,我从Pattern_file中的每一行的最后一行和Input_file的第二个字段中删除了空格(如果它们不存在那么你可以从上面的代码中删除sub(/[[:space:]]+$/,"")sub(/[[:space:]]+$/,"",$2)。我也删除像()[]这样的字符以避免任何错误匹配(虽然仅检查条件,但实际内容将打印在其中)。

2-此外,我已将整个文件(模式一)保存到一个数组中,然后对于Input_file的每一行,我检查它是否匹配数组中的任何内容,如果匹配则设置标志。

3-如果未设置标志,则表示未找到匹配,因此从Input_file打印内容。


2
投票

假设你想要部分的字符串匹配:

awk '
BEGIN { FS="[|]{3}" }
NR==FNR { a[$0]; next }
{
  for (str in a) {
      if ( index($5,str) ) {
          next
      }
  }
}
1'  pattern_file  Input_file
© www.soinside.com 2019 - 2024. All rights reserved.