Eu tenho um arquivo de texto com formato word @@@ type @@@ sentence
em cada linha, classificado por 'palavra' em ordem crescente. Algumas linhas, entretanto, não são únicas e começam com a mesma palavra da linha anterior, ou seja, veja a palavra1 abaixo:
...
word0 @@@ type2 @@@ sentence0
word1 @@@ type1 @@@ sentence1
word1 @@@ type1 @@@ sentence2
word1 @@@ type1 @@@ sentence3
word1 @@@ type2 @@@ sentence4
word2 @@@ type1 @@@ sentence5
...
Quero juntar as linhas que possuem a mesma combinação de palavras e tipos em uma só, anexando as frases, para que o arquivo resulte em:
...
word0 @@@ type2 @@@ sentence0
word1 @@@ type1 @@@ sentence1 ;;; sentence2 ;;; sentence3
word1 @@@ type2 @@@ sentence4
word2 @@@ type1 @@@ sentence5
...
Os campos word e type não possuem espaços em branco.
Responder1
Supondo que sua entrada esteja classificada nos campos word
e type
conforme aparece na entrada de amostra postada:
$ cat tst.awk
BEGIN { FS=" @@@ "; ORS="" }
{ curr = $1 FS $2 }
curr != prev {
printf "%s%s", ORS, $0
prev = curr
ORS = RS
next
}
{ printf " ;;; %s", $NF }
END { print "" }
$ awk -f tst.awk file
word0 @@@ type2 @@@ sentence0
word1 @@@ type1 @@@ sentence1 ;;; sentence2 ;;; sentence3
word1 @@@ type2 @@@ sentence4
word2 @@@ type1 @@@ sentence5
O procedimento acima funcionará usando qualquer awk em qualquer shell em cada caixa UNIX, armazena apenas 1 linha por vez na memória e produzirá saída na mesma ordem da entrada.
Responder2
Aqui está uma maneira, no awk:
$ awk -F'@@@' '{ $1 in a ? a[$1][$2]=a[$1][$2]" ;;; "$3 : a[$1][$2]=$3}END{for(word in a){for (type in a[word]){print word,FS,type,FS,a[word][type]} }}' file
word0 @@@ type2 @@@ sentence0
word1 @@@ type1 @@@ sentence1 ;;; sentence2 ;;; sentence3
word1 @@@ type2 @@@ ;;; sentence4
word2 @@@ type1 @@@ sentence5
Ou, de forma um pouco mais legível:
awk -F'@@@' '{
if($1 in a){
a[$1][$2]=a[$1][$2]" ;;; "$3
}
else{
a[$1][$2]=$3
}
}
END{
for(word in a){
for (type in a[word]){
print word,FS,type,FS,a[word][type]
}
}
}' file
Observe que isso requer uma awk
implementação que entenda arrays multidimensionais, como GNU awk( gawk
), que é o padrão awk
em sistemas Linux.