
Arquivo de entrada
CARD SG CLASS ATT
11 0 DAS YES
CARD SG CLASS ATT
12 0 ECT YES
CARD SG CLASS ATT
13 0 VAS YES
1 DAS NO
CARD SG CLASS ATT
14 0 SAT YES
CARD SG CLASS ATT
15 0 CDT YES
1 VEG YES
2 GAT NO
Espere o resultado:
CARD SG CLASS ATT
11 0 DAS YES
12 0 ECT YES
13 0 VAS YES
13 1 DAS NO
14 0 SAT YES
15 0 CDT YES
15 1 VEG YES
15 2 GAT NO
O que eu fiz:
awk ' /YES|NO/{VAL=$1};/ATT/{Print "CARD" "SG" "CLASS" "ATT" };/YES|NO/{ print VAL, $2, $3, $4} ' SCGR.txt | column -t
11 0 DAS YES
12 0 ECT YES
13 0 VAS YES
1 DAS NO
14 0 SAT YES
15 0 CDT YES
1 VEG YES
2 GAT NO
Por favor, eu ajude
Responder1
Tente isto (assumindo que todas as linhas do cabeçalho sejam exatamente iguais):
awk ' NR==1{header=$0; count=NF; print; next}
($0~header) {next}
(NF==count) {col1=$1}
(NF<count) {printf("%s",col1)}
1 ' infile | column -t
Responder2
Depurando seu único ligner - Vários pequenos problemas:
Print
--print
/ATT/{Print "CARD" "SG" "CLASS" "ATT" }
--/ATT/{print}
ou/ATT/;
/YES|NO/{VAL=$1}
também é acionado nos registros dos 3 campos, limpando o valor salvo anteriormente. (alterar a ordem ou$4 ~ /YES|NO/
)
Uma variante:
awk 'NF==4{v=$1;print} NF==3{print v,$0}'
removendo cabeçalhos extras e recuo:
awk '/^CARD/ && NR>1 { next }
NF==4 { v=$1;print }
NF==3 { print v,$0 }'
Responder3
Se não nos importamos com o alinhamento das colunas e queremos apenas dados normalizados separados em branco, o padrão básico é:
awk -F' +' '{ $1 = ($1 ~ /^$/ ? prev : $1); prev = $1; print }'
Veja, se configurarmos um separador de campos personalizado que não seja igual ao espaço padrão, conseguiremos uma verdadeira separação de campos. Se o registro começar com uma correspondência para o separador, um campo vazio será delimitado.
Por padrão, o Awk não separa; ele tokeniza: extrai de cada registro tokens que são sequências de um ou mais caracteres não-brancos/não-nova linha. Isso significa que espaços em branco/novas linhas iniciais e finais são ignorados. Portanto, se você tiver uma coluna 1 ausente, o valor na coluna 2 se tornará a coluna 1.
Com nosso / +/
regex separador, obtemos um verdadeiro comportamento de separação. Um registro com espaços à esquerda e à direita como 1 2 3 4
é tratado como <SEP>1<SEP>2<SEP>3<SEP>4<SEP>
. Portanto, existem seis campos: ""
, "1"
, ..., "4"
, ""
. Existe um campo antes do primeiro <SEP>
e depois do último.
A propósito, se o primeiro registro tiver um campo ausente, obviamente precisaremos de um padrão para prev
. Também não queremos que a lógica se aplique aos títulos. Também vamos substituir o operador ternário por um if
: Assim:
awk 'BEGIN { FS = " +"; prev = 0 }
NR == 1
NR > 1 { if ($1 == "") $1 = prev
print
prev = $1 }'
FOO BAR BAZ
FOO BAR BAZ
2 3 4
0 2 3 4
1 2 3 4
1 2 3 4
2 3 4
1 2 3 4
Responder4
Só pela educaçãoseddecisão
sed '
1b #output 1st line (header)
$!N #add next line to operate 2 lines altogether
s/\(.*\)\n\(CARD.*\)/\2\n\1/ #move line with CARD to first place
/^CARD/D #delete line with CARD and go to start
s/^\(\([0-9]*\s*\).*\n\)\s\s*/\1\2/
#repeat 1st field of 1st line if empty in 2nd
/\n/{P;D} #print&remove 1st line, go to start
'