mesclar linhas duplicadas em colunas

3

Dado um arquivo como este:

x y y z x
x x y z z y
x x x z y
y z z y x x x
x x x x x

Eu gostaria que a saída fosse:

x y+ z x
x+ y z+ y
x+ z y
y z+ y x+
x+

Isso é possível com awk ou perl em um oneliner? ou seja, é possível encontrar qualquer número de valores semelhantes em linhas e mesclá-los?

    
por spal78 29.12.2015 / 11:29

2 respostas

4

Esta versão perl também pode lidar com comprimentos de campo arbitrários, não apenas aqueles de um único caractere:

$ perl -lpae 'for $i (@F){s/($i\s*){2,}/$i+ /g}' file 
x y+ z x
x+ y z+ y
x+ z y
y z+ y x+ 
x+ 

Em um arquivo mais complexo:

$ cat file
foo foo foo bar foo
bar foo bar bar foo
foo foo x x x bar
$ perl -lpae 'for $i (@F){s/($i\s*){2,}/$i+ /g}' file 
foo+ bar foo
bar foo bar+ foo
foo+ x+ bar

Explicação

O -l apara novas linhas de cada linha de entrada, os campos -a divide os espaços no espaço em branco na matriz @F e -p imprime cada linha de entrada depois de aplicar o script fornecido por -e .

O próprio script itera sobre cada campo de entrada (a matriz @F ), salvando cada um como $i . A substituição procura por 2 ou mais $i consecutivos seguidos por 0 ou mais espaços e os substitui por $i+ .

    
por 29.12.2015 / 11:49
6
sed 's/\(.\)\( \)\{1,\}/+/g' <in >out
x y+ z x
x+ y z+ y
x+ z y
y z+ y x+
x+

Com BSD ou GNU sed :

sed -Ee's/(.)( )+/+/g' <in >out

Para trabalhar com comprimentos de campo arbitrários, basta fazer isso com comprimentos de campo arbitrários:

sed -Ee 's/(...)( )+/+/g' <<""
xxx yyy yyy zzz xxx
xxx xxx yyy zzz zzz yyy
xxx xxx xxx zzz yyy
yyy zzz zzz yyy xxx xxx xxx
xxx xxx xxx xxx xxx
xxx yyy+ zzz xxx
xxx+ yyy zzz+ yyy
xxx+ zzz yyy
yyy zzz+ yyy xxx+
xxx+

Ou com a entrada de @terdon ligeiramente modificada na segunda linha:

sed -Ee's/(([^ ]+ *)+)( +)+/<>+/g' <<""
foo foo foo bar foo
bar foo bar foo
foo foo x x x bar
<foo>+ bar foo
<bar foo>+
<foo>+ <x>+ bar
    
por 29.12.2015 / 11:35