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 hello
porque 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 grep
podrías ejecutar:
grep -oFf file1 file2 | sort | uniq | grep -Ff - file1
elimine el último grep
si 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
.