busque una cadena de un archivo en otro, si no está presente, elimínela del archivo original

busque una cadena de un archivo en otro, si no está presente, elimínela del archivo original

Estoy tratando de crear una secuencia de comandos que revise cada línea de un archivo y, si una línea no coincide en ningún lugar de cualquier línea de otro archivo de texto, elimine esa línea del archivo original.

Un ejemplo de entrada y salida deseada de este script sería:

entrada de ejemplo: archivo 1 (archivo 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

Ejemplo de salida del script: el archivo 1 cambió a:

hello
hi
great
interesting

Entonces se eliminó hi helloporque no está presente en el segundo archivo.

Aquí está el script, parece funcionar hasta el punto de hacer las variables.

#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

Respuesta1

Si es así, gnu greppodrías ejecutar:

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

elimine el último grepsi no es necesario conservar el orden de las líneas file1.
Si no tienes acceso a gnu grep, con 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

Respuesta2

Busque la respuesta de don_crissti (aceptada) si la tiene GNU grep. En caso de que no lo haga (por ejemplo, en un Mac OS X estándar, donde eso no funcionará), también puede guardar este fragmento en un script bash, por ejemplomyconvert.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"

Llámalo con los dos archivos como argumentos.

./myconvert.sh file1 file2

Sin embargo, tenga en cuenta los comentarios informados de don_crissti a continuación sobre el uso de while/read y los obvios inconvenientes de rendimiento de invocar sed.

información relacionada