Eu tenho o seguinte quadro de dados que continua indefinidamente na horizontal e na vertical, com números negativos apenas nas colunas ímpares:
-1 2 3 4 -5 9
2 3 -4 5 -6 11
E eu quero a 2ª, 4ª e 6ª colunas completas (ou todas as colunas pares) e os sinais de menos apenas da 1ª, 3ª e 5ª (ou todas as colunas ímpares), então entendi o seguinte:
- 2 4 - 9
3 - 5 - 11
E, eventualmente, acabe com isso:
-2 4 -9
3 -5 -11
Então, eu preciso dos valores das colunas pares inalteradas e das colunas ímpares, se houver um valor negativo, mantenha o - only e se houver um valor positivo, descarte-o.
Existe uma maneira de fazer isso com o awk / sed?
Isso é o mais longe que eu entendo:
awk '{ for (i=2;i<=NF;i+=2) $i="" }1' FILE.txt | sed 's/[0-9,.]*//g'
text-processing
sed
awk
Como encontrado
fonte
fonte
Respostas:
Aqui está uma maneira:
O
awk
script passa por todas as colunas ímpares e define seu valor como-
negativo ou vazio. Em seguida,sed
remove todos os espaços após-
ae substitui vários espaços consecutivos por um único. Observe que isso significa que o alinhamento será interrompido, pois alguns campos terão dois caracteres ou mais e outros terão um. Isso não será um problema se você estiver trabalhando com campos, eles simplesmente não parecem bonitos.fonte
O
sed
caminho:Resultado:
A primeira expressão mata a coluna à direita se houver um número ímpar de colunas. Faz isso procurando 0 ou mais pares
<number> <number>
, onde o primeiro número pode ser negativo.Edit: Uma
sed
solução mais curta , inspirada em @mikeserv:A mesma coisa com
perl
:Outra maneira com
perl
(provavelmente a mais limpa):fonte
Um
perl
:-an
dividir entrada para@F
matrizBEGIN{$,=" "}
definir separador de campo de saída para um espaçogrep{!($_%2)}0..$#F
obtém todos os índices pares na@F
matriz, que são índices de elementos ímparesmap{$_=$F[$_]=~/^-/?"-$F[$_+1]":" $F[$_+1]"}
verifique se o elemento ímpar começa com-
, em seguida, acrescente-
ao próximo elemento par; caso contrário, adicione um espaçofonte
Como resposta de @ terdon, mas sem o sed:
fonte
Uma
python
soluçãofonte
Uma
awk
solução simples baseada em matemática :i=2
) ao último campo (i<=NF
).$(i-1)
) por -1 ou 1.printf "%4s"
) e imprima uma nova linha à direita (print ""
).A única ressalva é que, se você tiver um número ímpar de colunas, o último campo não exibirá nada. Espero que seja isso que você espera.Aparentemente, é isso que você espera. :)(editado para trabalhar com valores decimais e para tornar as condições do loop mais alinhadas com a pergunta e salvar 2 caracteres.)
fonte
Você precisa esquecer completamente o negativo - deixe de fora. Você deseja consolidar dois campos - da esquerda para a direita. Isso é muito fácil.
Observe como evito qualquer referência ao sinal - quando a entrada é processada, o autômato aceita apenas espaços ou números porque não entende mais nada - todo o resto é completamente ignorado e permanece no local.
Quando você especifica um
\{
intervalo de repetição numérica\}
para uma\(
subexpressão\)
, apenas a última ocorrência dessa expressão é\1
referenciada novamente. Assim, você pode simplesmente apertar - ou truncar - um intervalo de repetição tão facilmente. E porque apertamos a repetição atrás do sinal - se houver um - a segunda ocorrência desse padrão seguirá qualquer sinal que precede o primeiro.O comportamento descrito acima é especificado pelo POSIX para todos os aplicativos compatíveis com BRE, mas muito poucos
sed
s acertam. GNUsed
faz.Por fim, os espaços são apenas para tornar a ocorrência do padrão regular .
Obviamente, isso nunca funcionará para você. Ou, provavelmente, mais corretamente, sempre funcionará para você, mas nunca retornará nenhum resultado. Como poderia se o padrão fosse indefinido ?
fonte