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

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

Estou tentando criar um script que examine cada linha de um arquivo e, se uma linha não corresponder a 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

Exemplo de saída de script - arquivo 1 alterado para:

hello
hi
great
interesting

Então foi removido hi hello, porque não está presente no segundo arquivo

aqui está o script, parece funcionar a 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

Responder1

Se você tiver, gnu grepvocê pode executar:

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

remova o último grepse 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

Responder2

Vá para a resposta (aceita) de don_crissti se você tiver GNU grep. Caso isso não aconteça (por exemplo, em um Mac OS X padrão, onde isso não funcionará), você pode alternativamente salvar esse trecho em um script bash, por exemplomyconvert.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 de invocar sed.

informação relacionada