Como separar a seqüência de caracteres (dígitos) por espaço

1

Eu tenho esta situação:

my data :

ID01 120120101
ID02 101010101
ID03 210210210
ID04 505052120

E eu queria esses dados: output

ID01 1 2 0 1 2 0 1 0 1
ID02 1 0 1 0 1 0 1 0 1
ID03 2 1 0 2 1 0 2 1 0
ID04 5 0 5 0 5 2 1 2 0

Então, eu queria separar todos os dígitos presentes na segunda coluna ( meus dados ), mas a primeira coluna deve permanecer intacta.

Para isso eu tentei criar dois arquivos: um com ID ($ 1-file1) e outro com a sequência que eu queria separar com espaços (file2). Depois que eu tentei:

sed -i -- 's//\t/g' file2

mas recebi o seguinte erro:

sed: -e expression #1, char 0: no previous regular expression

Como posso resolver isso?

    
por Amanda Botelho Alvarenga 05.10.2016 / 23:20

4 respostas

1

Que tal

perl -alne 'print join " ", $F[0], split("", $F[1])' data
ID01 1 2 0 1 2 0 1 0 1
ID02 1 0 1 0 1 0 1 0 1
ID03 2 1 0 2 1 0 2 1 0
ID04 5 0 5 0 5 2 1 2 0

Se você quiser a saída separada (totalmente) da guia, mude para

perl -alne 'print join "\t", $F[0], split("", $F[1])' data

ou se você deseja preservar uma guia após o ID , mas separar os dígitos do segundo campo,

perl -alne 'print join "\t", $F[0], join " ", split("", $F[1])' data
    
por 06.10.2016 / 03:04
1

Em sed , um regex vazio significa reutilizar o anterior, que neste caso você não possui. Se você tiver as colunas separadas, poderá fazer algo assim:

sed 's/./& /g' file2

(Combine qualquer caractere, depois substitua o que tivermos com & e adicione o espaço.)

Mas alterar apenas a segunda coluna é mais fácil de fazer com awk :

awk '{gsub(/./, "& ", $2)} 1' data 

gsub é praticamente o mesmo que s///g in sed. Tanto quanto eu posso testar awk suporta o regex vazio, mas isso adicionaria um espaço extra, uma vez que também coincide com o primeiro dígito. (Bem, o acima também adiciona um espaço extra ao final.)

    
por 05.10.2016 / 23:29
0

Não é lindo, mas funciona

cat my_data | sed -e 's/./ &/g' -e 's/^ \(.\) \(.\) \(.\) \(.\)  //'

A primeira expressão coloca um espaço antes de todas as letras. O próximo remove os espaços da primeira parte.

Você também pode criar um script:

#! /bin/bash
while read ID NUMBERS; do
    echo $ID$(echo $NUMBERS | sed -e 's/./ &/g')
done

e, em seguida, execute

cat my_data | ./my_script
    
por 05.10.2016 / 23:40
0

Quando não é possível usar o comando s com o sinalizador g , uma abordagem é usar o comando s em um loop com o comando t (um salto condicional para o s de sucesso ).

Aqui:

sed -e :1 -e 's/\([^ ]\)\([^ ]\{1,\}\)$/ /;t1'

Substitua um não-espaço seguido por uma sequência de 1 ou mais não-espaços no final da linha com esse não-espaço, um espaço e essa sequência de não-espaços e repete até que não possa substituir . Então, para cada linha, faz (aqui para a primeira linha):

ID01 120120101
-> ID01 1 20120101
-> ID01 1 2 0120101
-> ID01 1 2 0 120101
-> ID01 1 2 0 1 20101
-> ID01 1 2 0 1 2 0101
-> ID01 1 2 0 1 2 0 101
-> ID01 1 2 0 1 2 0 1 01
-> ID01 1 2 0 1 2 0 1 0 1
at this point the "s" command fails, so "t1" doesn't branch

com perl :

perl -pe 's/\S+$/join " ", split "", $&/e'
    
por 06.10.2016 / 00:07