
Este é o arquivo abc.txt
NAME="MARK" StartTime="14:11:26.710583" TotalElapsedTime="0" Pool="10" ThreadsReached="0"
NAME="MARK" StartTime="14:11:26.710583" TotalElapsedTime="0" Pool="10" ThreadsReached="0"
Precisa de uma saída no formato abaixo com abc.csv
NAME StartTime TotalElapsedTime Pool ThreadsReached
MARK 14:11:26.710583 0 10 0
MARK 14:11:26.710583 0 10 0
Responder1
Como o formato CSV básico assume a vírgula ,
como separador de campos, use o seguinte GNUsedabordagem:
sed -e '1iNAME,StartTime,TotalElapsedTime,Pool,ThreadsReached' -e 's/[^=]*="\([^"]*\)"/\1,/g; s/,$//g' file
A saída:
NAME,StartTime,TotalElapsedTime,Pool,ThreadsReached
MARK,14:11:26.710583,0,10,0
MARK,14:11:26.710583,0,10,0
1i
- inserçõescabeçalholinha antes da primeira linha do arquivo
s/[^=]*="\([^"]*\)"/\1,/g
- extraindo todos os valores de atributos
Responder2
while IFS= read -r l; do
set -f; IFS==; set -- $l; shift; N=$#
for arg
do
set -- ${1+"$@"} "$(expr " $arg" : ' "\(.*\)"')"
done
shift "$N"; IFS=,; echo "$*"
done < abc.txt
while IFS= read -r l; do
set -f; IFS==; set -- $l; shift
while case ${#} in 1 ) break ;; esac; do
expr " $1" : ' "\(.*\)"'
shift
done | tr \\n ,; expr " $*" : '.*"\(.*\)"'
done < abc.txt
perl -lne '$,=",";
print /(?:^|\h)\K[^=]*/g if $. == 1;
print /="([^"]*)"/g;
' abc.txt
Explicações
- No código Perl, da primeira linha extraímos os nomes dos campos por meio do regex
/(?:^|\h)\K[^=]*/g
que é lido como get me the run ofnon=
Characters à esquerda dos quais é visto um espaço em branco horizontal\h
ou o início da linha^
. Em seguida, eles são impressos usando oOFS
$,
conjunto com vírgula. - Para todas as linhas (incluindo a primeira também), extraímos os valores do campo por meio do regex,
/="([^"]*)"/g
que deve ser lido como extrair a string entre os valores de aspas duplas (assumindo que não há aspas duplas escapadas) que são adjacentes a um sinal de igual nele. esquerda. A coleção desses valores é então unidastdout
ao arquivoOFS
. - No caso da
while
solução de loop, primeiro lemos a linha como ela está, sem divisão de palavras. Em seguida, definimos o IFS como an=
e rejeitamos o primeiro campo. Agora todos os campos terão o formato."..."...
Em seguida, usamos oexpr
utilitário para detalhar o valor entre aspas duplas e colocá-los no$@
array. No final dofor
loop removemos os elementos originais ($N
) então o que resta é o que queremos. Finalmente, eles são unidos pela vírgula, configurando IFS como vírgula e expandindo$*
.