Como transformar esses dados em designações usando o awk ou outro?

1

Eu preciso transformar alguns dados em atribuições. Tenho certeza que parece um trabalho bem direto para o awk, mas estou longe de ser confortável com isso.

Cada elemento de dados (e colunas) é separado por tabulações. Os elementos de dados podem conter espaços e caracteres especiais, mas não há TABs.

exemplo de entrada:

column1 column2 column3
rowA1   rowA2   rowA3
rowB1   rowB2   rowB3

resultado esperado:

column1 = rowA1
column2 = rowA2
column3 = rowA3

column1 = rowB1
column2 = rowB2
column3 = rowB3

(com número arbitrário de linhas, não excedendo centenas)

Alguma pista de como fazer isso? (com awk ou qualquer ferramenta de linha de comando padrão em um linux)

    
por Pac0 25.07.2017 / 10:10

2 respostas

5

Por exemplo:

{
    if (NR==1){
        for (i=1; i<=NF; ++i){
            arr[i] = $i
        }
    }else{
        for (i=1; i<=NF; ++i){
            print(arr[i]," = ",$i)
        }
    }
    print("")
}

Para executar:

awk -f script.awk input
    
por 25.07.2017 / 10:23
3
cat data |
while IFS=$'\t' read -r -a a; do
   case ${flag+'set'} in
      "set" )
         set -- "${a[@]}"
         for c in "${C[@]}"; do echo "$c = $1"; shift; done
         echo ;;

      * ) C=( "${a[@]}" ); flag= ;;
   esac
done

sed -Ee '
   1h;1N
   /^\n$/{
      $d;P;g;N
   }
   s/^(\S+)\s*((\S.*)?)\n(\S+)\s*((\S.*)?)/ = \n\n/
   P;D
' data

perl -F'\t+' -lane '
   @C or @C = @F,next;
   print "$C[$_] = $F[$_]" for 0 .. $#C;
   eof or print q[];
' data

Resultado

column1 = rowA1
column2 = rowA2
column3 = rowA3

column1 = rowB1
column2 = rowB2
column3 = rowB3

Explicação

  1. bash

    *) Armazene a primeira linha em uma matriz C durante o tempo em que o sinalizador estiver desfeito. Em seguida, defina-o imediatamente para que, da próxima vez, não cheguemos até aqui. *) A matriz a é dividida em argumentos usando o comando set . *) Então, percorremos as colunas acessadas via "$ {c [@]}" em um loop for e imprimimos juntamente com $ 1 (que é então deslocado para fora) *) Nota O IFS está configurado para tab através da construção $'\t' . Uma vez que é um dos caracteres especiais, portanto, uma série desses seria recolhida em um e, portanto, não veríamos campos vazios.

  2. perl

    *) Defina o FS para um ou mais TABs: -F'\t+' e ative o modo autosplit. *) Mesma lógica que com a solução baseada em bash , em que armazenamos os dados das colunas encontrados na 1ª linha na matriz @C . Os arrays @C e os dados dos campos de registro atuais em @F são impressos, tomando um de cada.

  3. sed

    *) Aqui primeiro convertemos todos os TABs em espaços. *) Armazene os dados das colunas da primeira linha no espaço de armazenamento. *) Para todas as outras linhas, anexe as colunas à linha atual. *) Continuamos escolhendo os primeiros elementos da linha / coluna atual e diminuindo o espaço padrão tirando esses materiais impressos. *) A condição de parada acontece quando não há espaços restantes.

por 25.07.2017 / 14:08

Tags