Minha awk
proposição:
awk -F'|' '{ if (a[$1$2] == "") {
a[$1$2] = $0
}
else {
a[$1$2] = a[$1$2]","$3"|"$4"|"$5"|"$6
}
}
END {
for (key in a) {
print a[key]
}
}' <input.txt | sort
Explicação
A opção -F'|'
define o separador de campos (que awk
usa para analisar campos dentro de uma linha) como caractere '|', pois é assim que o arquivo é formatado.
a[...]
é uma matriz. Matrizes em awk
funcionam um pouco como os dicionários de python, em vez de índices você pode ter chaves que são de fato cadeias de caracteres. Para cada linha do arquivo de entrada, o teste if (a[$1$2] == "")
verifica a chave que corresponde aos dois primeiros campos ( $1$2 = A1
para a primeira linha, por exemplo) se houver uma entrada. Se não (primeiro A|1|...
linha lida), toda a linha é armazenada nessa chave ( a[$1$2] = $0
). Se já houver algo (outra A|1|...
line já foi armazenada), então concatenaremos a entrada com uma vírgula e os campos de 3 a 6 serão separados por "|" ( a[$1$2] = a[$1$2]","$3"|"$4"|"$5"|"$6
).
Finalmente, quando passamos pelo arquivo, precisamos exibir as entradas para cada chave. Fazemos isso em um bloco END
(essas instruções são executadas quando todo o arquivo é lido). Para fazer isso, simplesmente passamos por todas as chaves da matriz ( for (key in a)
) e imprimimos a entrada para cada uma delas.
A saída final é canalizada para sort
, porque awk
não será executado por meio de chaves de matriz em ordem alfanumérica, portanto, é mais limpo classificar a saída para obter a linha A|1|...
seguida por A|2|...
e assim por diante.
Sua última edição tornou a coisa toda um pouco mais complicada. As instruções awk
necessárias ficarão um pouco confusas, então aconselho que você crie um arquivo de script awk
(crie um arquivo de texto com .awk
extensão, por exemplo, myScript.awk
). Copie o seguinte script dentro dele:
BEGIN { FS="|" }
$3 == "DLT" {
dlt[$1"|"$2]=$3"|"$4"|"$5"|"$6
a[$1"|"$2]++
}
$3 == "STG" {
stg[$1"|"$2]=$3"|"$4"|"$5"|"$6
a[$1"|"$2]++
}
$3 == "MAIN" {
main[$1"|"$2]=$3"|"$4"|"$5"|"$6
a[$1"|"$2]++
}
$3 == "UNLD" {
unld[$1"|"$2]=$3"|"$4"|"$5"|"$6
a[$1"|"$2]++
}
END {
for (key in a) {
if (dlt[key] == "") dlt[key]="|||"
if (stg[key] == "") stg[key]="|||"
if (main[key] == "") main[key]="|||"
if (unld[key] == "") unld[key]="|||"
print key"|"dlt[key]"|"stg[key]"|"main[key]"|"unld[key]
}
}
Para usá-lo:
awk -f myScript.awk <input.txt | sort
Se você entendeu a explicação para a minha resposta inicial, você deve ser capaz de entender esse algoritmo. Desta vez, fazemos uma matriz para cada tipo de dados (dlt, stg, main e unld) e armazenamos seus valores na chave correspondente aos dois primeiros campos. A matriz " a
" é usada para rastrear todas as chaves possíveis. No final, percorremos as chaves da matriz a
e, se uma das matrizes de dados estiver vazia nessa chave, preencha-a "|||" como você queria, para que cada linha acabe com 18 campos.