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 grep
você 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
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
.