$ awk -F'|' '
NR==1 { header=$0 };
NR>1 && ($3 > colC[$1]) { colC[$1] = $3 ; line[$1] = $0};
END {
print header;
for (i in line) { print line[i] }
}' file.log
columnA | colB | colC | colD
name_1| data | 3 | data
name_2| data | 2 | data
Usando | como o separador de campo, esse script awk salva a primeira linha na variável header , então usa a matriz colC para manter, para cada valor da coluna A ( $1 ), o maior valor visto na coluna C ($ 3). A matriz line também é usada para armazenar toda a linha de entrada correspondente ( $0 ).
Finalmente, quando toda a entrada foi lida e processada, ela imprime cada linha salva. Provavelmente, a saída precisará ser classificada, pois as matrizes associativas não são armazenadas em nenhuma ordem específica - canalize a saída para sort . Dependendo do arquivo de entrada, a linha de cabeçalho pode acabar sendo classificada no meio da saída ou no final ... se for esse o caso, provavelmente é melhor não salvá-lo ou imprimi-lo no script awk , mas imprimir no script de shell que executa o script awk.
OBSERVAÇÃO: Existem várias maneiras de otimizar esse algoritmo, que optei por otimizar por legibilidade e simplicidade. A menos que seus arquivos de entrada tenham milhões ou bilhões de linhas, é improvável que o desempenho e o consumo de memória sejam um problema que vale a pena otimizar.