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
-
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.
-
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.
-
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.