Posso fazer dois arquivos uns contra os outros?

3

Eu quero grep file A para cada frase no arquivo B, onde uma frase é uma string de palavras de tamanho X. Idealmente, seria um grep aproximado, como agrep. Existe uma maneira de fazer isso usando ferramentas de linha de comando?

    
por Jonathan 26.02.2016 / 17:42

3 respostas

2

Com zsh , você pode tentar algo como:

x=3
B_words=($(<B))
A_words=($(<A))
A="$A_words"

setopt extendedglob
for ((i = 1; i<=$#B_words - x + 1; i++)) {
  phrase=$B_words[i,i+x-1]
  [[ " $A " = (#a2)*" $phrase "* ]] && printf '%s\n' $phrase
}

Qual deve dar-lhe as seqüências de 3 palavras do arquivo B que também são encontradas no arquivo A (permitindo 2 erros com (#a2) ).

Por exemplo, se A for sua pergunta e B for a sentença acima, recebo:

of 3 words
3 words of
in file A

Ou se você quiser ver o que foi correspondido no arquivo A :

for ((i = 1; i<=$#B_words - x + 1; i++)) {
  phrase=$B_words[i,i+x-1]
  [[ " $A " = (#a2)(#b)*" "($phrase)" "* ]] &&
    printf '%s\n' "$phrase ($match[1])"
}

que dá:

of 3 words (of words)
3 words of (words of)
in file A (in file B,)

palavras aqui são definidas como sequências de caracteres não-IFS que com o valor padrão de $ IFS é qualquer caractere diferente de espaço, tabulação, nova linha e nul.

    
por 26.02.2016 / 18:21
0

Você pode usar o diff enquanto estiver preocupado com linhas inteiras:

diff file1 file2 --old-line-format='' --new-line-format='' --unchanged-line-format='%L'

O old-line-format refere-se às linhas apenas no primeiro arquivo, o formato está em branco para deixá-las de fora.

O new-line-format refere-se às linhas apenas no segundo arquivo, o formato está em branco para deixá-las fora.

O unchanged-line-format refere-se a linhas em ambos os arquivos, e o formato '%L' é para imprimir a linha incluindo sua quebra de linha.

Você pode ver mais sobre a formatação da saída do diff aqui: link

    
por 26.02.2016 / 18:55
-1

Fácil, basta executar cat A | grep -f B para o script padrão ou simples:

#!/bin/bash

IFS=' ' read -ra ADDR <<< $(cat "$1")

read -ra ADDR2 <<< $(cat "$2")

for i in "${ADDR[@]}"; do

    for n in "${ADDR2[@]}"; do

    if [[ "$i" -eq "$n" ]]; then

        echo $n

    fi

    done

done

e execute-o com arquivos como parâmetros ./scritp.sh A B

    
por 26.02.2016 / 17:52