Use SED ou AWK para mover a string para a nova coluna e linha

1

Eu tenho um arquivo .csv delimitado por tabulações e preciso mover as informações da linha de cabeçalho para uma coluna "nova" no início e um número especificado de linhas para baixo. Eu gostaria de usar ferramentas padrão que eu uso atualmente, como sed ou awk , mas se outra ferramenta / método é mais apropriado, eu gostaria de receber a sugestão. O cabeçalho muda por arquivo, é por isso que eu preciso copiá-lo em vez de apenas colocar a string "CAT" na linha e coluna apropriadas.

                            CAT
    DOG     DOG     DOG     DOG     DOG     DOG     DOG
    DOG     DOG     DOG     DOG     DOG     DOG     DOG
    DOG     DOG     DOG     DOG     DOG     DOG     DOG
    DOG     DOG     DOG     DOG     DOG     DOG     DOG

se tornaria:

                            CAT
            DOG     DOG     DOG     DOG     DOG     DOG     DOG
            DOG     DOG     DOG     DOG     DOG     DOG     DOG
    CAT     DOG     DOG     DOG     DOG     DOG     DOG     DOG
            DOG     DOG     DOG     DOG     DOG     DOG     DOG
    
por user72055 10.06.2014 / 16:39

5 respostas

1

paste também pode:

editado

Isto imprime a primeira linha novamente. Aproveitando a falta de cotações, os espaços à direita não estão aparecendo:

$ paste -d"\t" <(printf "\n\n\n%s" $(head -1 file)) file
                                    CAT
            DOG     DOG     DOG     DOG     DOG     DOG     DOG
            DOG     DOG     DOG     DOG     DOG     DOG     DOG
CAT         DOG     DOG     DOG     DOG     DOG     DOG     DOG
            DOG     DOG     DOG     DOG     DOG     DOG     DOG

original

$ -d"\t" <(printf "\n\n\nCAT") file
                                    CAT
            DOG     DOG     DOG     DOG     DOG     DOG     DOG
            DOG     DOG     DOG     DOG     DOG     DOG     DOG
CAT         DOG     DOG     DOG     DOG     DOG     DOG     DOG
            DOG     DOG     DOG     DOG     DOG     DOG     DOG
    
por 10.06.2014 / 16:48
1

O seguinte comando sed funciona para mim:

sed '1!s/^/\t/;4s/^/CAT/' 

Interpretação:

Nas linhas diferentes do número 1, substitua o início da linha por uma guia. Na quarta linha, substitua o início da linha pela string CAT.

    
por 10.06.2014 / 16:45
1

Você pode usar sed da seguinte maneira:

  1. salve a primeira linha no hold space
  2. prefixar uma guia extra (coluna) da linha 2 em diante (isso preserva o alinhamento original da coluna do cabeçalho)
  3. em uma linha seguinte especificada (usei a linha 4 no exemplo abaixo), troque o hold de volta para pattern space, retire o espaço em branco dele e coloque-o na linha

$ sed -e '1h' -e '2,$s/^/\t/' -e '4{x;s/[[:space:]]//g;G;s/\n//}' file
                                CAT
                DOG     DOG     DOG     DOG     DOG     DOG     DOG
                DOG     DOG     DOG     DOG     DOG     DOG     DOG
    CAT         DOG     DOG     DOG     DOG     DOG     DOG     DOG
                DOG     DOG     DOG     DOG     DOG     DOG     DOG
    
por 10.06.2014 / 17:35
0

Você também pode tentar este comando awk.

$ awk 'NR==1{var=$1} {sub (/^     /,"            ");} NR==4{ sub (/^ +/,""); $0="    "var"     "$0}1' file
                                    CAT                        
            DOG     DOG     DOG     DOG     DOG     DOG     DOG
            DOG     DOG     DOG     DOG     DOG     DOG     DOG
    CAT     DOG     DOG     DOG     DOG     DOG     DOG     DOG
            DOG     DOG     DOG     DOG     DOG     DOG     DOG

Ele busca a string na primeira linha e depois anexa a mesma string no começo da linha 4.

    
por 10.06.2014 / 17:14
0

Usando awk :

awk -v line=4 -F '^\t*|\t+' '
  NR==1 { OFS="\t"; ins=$2 }
  NR!=line { print "","",$0 }
  NR==line { print "",ins,$0 }' file

Isso usará o primeiro campo não vazio da linha de cabeçalho como o texto a ser inserido, para que ele possa ter qualquer texto além de uma guia ou nova linha. O separador de campo está configurado para que seja sempre lido como o segundo campo em awk .

    
por 10.06.2014 / 18:50