Script de shell simples para adicionar linhas do arquivo newdata to datafile . Deve ser fácil alterar newdata para um aqui-doc. Isso realmente não é muito eficaz, pois chama grep para cada (nova) linha de entrada:
target=datafile
while IFS= read -r line ; do
if ! grep -Fqxe "$line" "$target" ; then
printf "%s\n" "$line" >> "$target"
fi
done < newdata
Para cada linha, usamos grep para ver se ela já existe no arquivo de destino, -F para correspondência de sequência fixa (sem expressões regulares), -x para correspondência de linha completa e -q para suprimir saída de linhas combinadas. grep retorna um código de erro falso se não encontrar uma linha correspondente, então acrescente ao arquivo de destino se o resultado negado for verdadeiro.
Mais efetivamente, em awk . Isso depende de awk poder manipular linhas arbitrárias como chaves para um array.
$ awk 'FNR == NR { lines[$0] = 1; next } ! ($0 in lines) {print}' datafile newdata
A primeira parte FNR == NR { lines[$0] = 1; next } carrega todas as linhas do primeiro arquivo de entrada como chaves na matriz (associativa) lines . A segunda parte ! ($0 in lines) {print} é executada nas seguintes linhas de entrada e imprime a linha se não estiver na matriz, ou seja, nas "novas" linhas.
A saída resultante contém apenas as novas linhas, por isso precisa ser anexada ao arquivo original, por exemplo, com sponge :
$ awk 'FNR == NR { lines[$0] = 1; next } ! ($0 in lines) {print}' datafile newdata | sponge -a datafile
Ou poderíamos ter awk anexando as linhas à linha final, isso exige apenas passar o nome do arquivo para awk :
$ target=datafile
$ awk -vtarget="$target" 'FNR == NR { lines[$0] = 1; next }
! ($0 in lines) {print >> target}' "$target" newdata
Para usar um aqui-doc com awk , precisaremos adicionar - (stdin) como um arquivo de origem explícito, além de definir o redirecionamento, portanto awk ... "$target" - <<EOF