corresponde a pelo menos dois padrões de outro arquivo

3

o código básico para procurar uma correspondência por uma string

cat fileA | grep -Fwf include.txt

Como podemos usar um código para corresponder a pelo menos dois padrões daquele include.list

file A 
data1 khc001 khc002 vp005
data1 fbc001 cs004 khc001

include.txt
khc001
khc002

linha de saída correta 1: data1 khc001 khc002 vp005

no exemplo a seguir, apenas dois padrões são listados, mas a lista contém muito mais É por isso que awk '/pattern1/ && /pattern2/' não é apropriado.

    
por Enrik S 18.05.2018 / 21:28

5 respostas

4

Seria bastante fácil fazer isso com awk , contando o número de campos em cada linha em fileA que são iguais às sequências no arquivo include.txt :

awk 'NR == FNR { p[$1]; next }
     {
         c = 0
         for (i = 1; i <= NF; ++i) if ($i in p) c++
         if ( c >= 2 ) print
     }' include.txt fileA

Primeiro, lê o arquivo include.txt e usa as palavras como chaves em um array associativo. Em seguida, ele lê o segundo arquivo e, para cada linha, itera nos campos e testa cada um para ver se ele corresponde a alguma das chaves.

Para cada partida, incrementamos um contador e, se o contador for igual ou maior que dois no final, imprimiremos a linha.

Formulação alternativa do código para pessoas que gostam de "one-liners":

awk 'NR==FNR {p[$1];next} {c=0;for (i=1;i<=NF;++i) if ($i in p) c++} c>=2' include.txt fileA
    
por 18.05.2018 / 21:46
1

Isso deve funcionar assumindo que a ordem dos padrões é a mesma do arquivo de entrada, mas não da ordem errada:

grep -F " $(tr '\n' ' ' <patterns)" infile
    
por 18.05.2018 / 22:16
0

Consegui fazer isso com a seguinte percepção:

grep -Fwf <(grep -v $(grep -oFwf include.txt fileA | head -1) include.txt) fileA

Isso removerá um dos padrões correspondentes de include.txt e garantirá que haja pelo menos uma outra correspondência.

    
por 18.05.2018 / 21:54
0

Outro awk

awk '
  NR==FNR {
    a[NR]=$0
    next }
  !b { b=NR }
  {
    c=$0
    for(i=1;i<b;i++)
        if(!sub("\<"a[i]"\>","",c))
            next
  }1
' include.txt file\ A

Try to remove each word from include.txt in each line.

If a word is not remove not print the line.

    
por 18.05.2018 / 23:01
0
grep -Fwonf include.txt file_A | 
uniq | 
cut -d: -f1 | 
printf '%dp\n' $(uniq -d) | 
ed -s file_A 

Teste

O conteúdo dos arquivos (arquivo_A mais complicado para testes):

$ tail -n +1 -- file_A include.txt 
==> file_A <==
data1 khc001 khc002 vp005
data1 fbc001 cs004 khc001
data1 khc001 khc001 vp005
data1 khc002 khc001 vp005

==> include.txt <==
khc001
khc002

Resultado

data1 khc001 khc002 vp005
data1 khc002 khc001 vp005
    
por 20.05.2018 / 00:22