encontrar string de um arquivo em outro se não estiver presente, então remova do arquivo original

1

Estou tentando criar um script que examine cada linha de um arquivo e, se uma linha não corresponder a qualquer lugar em qualquer linha de outro arquivo de texto, remova essa linha do arquivo original.

Um exemplo de entrada e saída desejada deste script seria:

entrada de exemplo: arquivo 1 (arquivo de grupos),

hello
hi hello
hi
great
interesting

           file 2: 
this is a hi you see
this is great don't ya think
sometimes hello is a good expansion of its more commonly used shortening hi
interesting how brilliant coding can be just wish i could get the hang of it

Saída de script de exemplo - arquivo 1 alterado para:

hello
hi
great
interesting

Então, ele removeu hi hello , porque não está presente no segundo arquivo

aqui está o script, parece funcionar ao ponto de fazer as variáveis.

#take first line from stability.contigs.groups
echo | head -n1 ~/test_folder/stability.contigs.groups > ~/test_folder/ErrorFix.txt
#remove the last 5 character
sed -i -r '$ s/.{5}$//' ~/test_folder/ErrorFix.txt 

#find match of the word string in errorfix.txt in stability.trim.contigs.fasta if not found then delete the line containing the string in stability.contigs.groups
STRING=$(cat ~/test_folder/MothurErrorFix.txt)
FILE=~/test_folder/stability.trim.contigs.fasta
if [ ! -z $(grep "$STRING" "$FILE") ]
    then
        perl -e 's/.*\$VAR\s*\n//' ~/test_folder/stability.contigs.groups
fi
    
por Giles 21.05.2016 / 20:17

2 respostas

1

Se você tem gnu grep , pode executar:

grep -oFf file1 file2 | sort | uniq | grep -Ff - file1

remova o último grep se não precisar preservar a ordem das linhas em file1 .
Se você não tiver acesso a gnu grep , com awk :

awk 'NR==FNR{z[$0]++;next};{for (l in z){if (index($0, l)) y[l]++}}
END{for (i in y) print i}' file1 file2
    
por 22.05.2016 / 00:29
0

Ir para a resposta (aceito) de don_crissti se você tiver GNU grep . Caso você não o faça (por exemplo, em um Mac OS X padrão, em que isso não funcione), você pode salvar esse snippet em um script básico, por exemplo, myconvert.sh

#!/bin/bash
while IFS='' read -r line || [[ -n "$line" ]]; do
    if ! grep -Fq "$line" $2
    then
        sed -i '' "/$(echo $line | sed -e 's/[]\/$*.^|[]/\&/g')/d" $1
    fi
done < "$1"

uma chamada com os dois arquivos como argumentos

./myconvert.sh file1 file2

No entanto, observe os comentários bem informados de don_crissti abaixo sobre o uso de while / read e as óbvias desvantagens de desempenho ao invocar sed .

    
por 21.05.2016 / 22:23