найти строку из одного файла в другом, если ее нет, то удалить из исходного файла

найти строку из одного файла в другом, если ее нет, то удалить из исходного файла

Я пытаюсь создать скрипт, который просматривает каждую строку одного файла и, если строка не совпадает ни с одной строкой другого текстового файла, удаляет эту строку из исходного файла.

Примером желаемых входных и выходных данных для этого скрипта может быть:

пример ввода: файл 1 (файл групп),

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

Пример выходных данных скрипта — файл 1 изменен на:

hello
hi
great
interesting

Итак, он удален hi hello, так как его нет во втором файле.

Вот скрипт, он, кажется, работает вплоть до создания переменных.

#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

решение1

Если у вас есть, gnu grepвы можете запустить:

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

удалите последний, grepесли не нужно сохранять порядок строк в file1.
Если у вас нет доступа к gnu grep, с помощью 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

решение2

Если у вас есть ответ don_crissti (принятый), перейдите к нему GNU grep. Если у вас его нет (например, на стандартной Mac OS X, где это не сработает), вы можете сохранить этот фрагмент в скрипте bash, например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"

и вызвать его с двумя файлами в качестве аргументов

./myconvert.sh file1 file2

Однако, пожалуйста, обратите внимание на содержательные комментарии don_crissti ниже относительно использования while/read и очевидных недостатков производительности при вызове sed.

Связанный контент