No bash, isso pode ser feito com comandos internos, tail
e cut
:
#! /bin/bash
# Get header line
header=$( head -n 1 data_file )
# Make a variable with all delimiters (2)
delimiters=${header//[^;]/}
# Make an array with all column names
declare -a colnames=( ${header//;/ } )
# For all columns one at the time...
for C in $(seq 2 $((${#delimiters}+1)) ) ; do
index=$((C-1))
# Skip first 3 lines of data_file
tail --lines=+3 data_file | cut -d\; -f1,$C | while read; do
# Replace first ';' with column name
line=${REPLY/;/;${colnames[$index]};}
# Remove all spaces and print
echo ${line// /}
done
done
Explicação:
Obtenha a primeira linha do arquivo em uma variável (que pode ser modificada)
header=$( head -n 1 data_file )
Remova todos os caracteres da variável espere o delimitador cemi-cólon
delimiters=${header//[^;]/}
Agora, a variável $ delimiters contém ';;'
Substitua todos os ';' com espaços. Vai dar "N A B". Um ou mais espaços é o delimitador da matriz:
declare -a colnames=( ${header//;/ } )
Obtenha o número de caracteres em uma variável:
${#delimiters}
Adicione um:
$((${#delimiters}+1))
Então
$(seq 2 $((${#delimiters}+1)) )
é igual a:
$(seq 2 3 )
O índice na variável vai de 0..n, depois -1 para procurar nomes de coluna:
index=$((C-1))
Leia o arquivo, pule as 3 primeiras linhas, mostre apenas o número da coluna $C
, leia a linha na variável $REPLY
:
tail --lines=+3 data_file | cut -d\; -f1,$C | while read; do