Como obter contagem de dados entre duas cadeias de caracteres com várias ocorrências no mesmo arquivo

0

Eu tenho os dados no meu arquivo como

START-OF-FIELDS
ID
NAME
DEPT
END-OF-FIELDS

START-OF-DATA
1|joy|cs
2|sam|ec
END-OF-DATA

START-OF-FIELDS
ID 
NAME
DOB
DEPT
ADDRESS
END-OF-FIELDS

START-OF-DATA
5|joe|13/2/2001/|ee|street1
3|gwen|4/08/1999|cs|street2
END-OF-DATA

SAÍDA ESPERADA: -

ID
NAME
DEPT

A contagem do conjunto de dados 1 é: 3

ID 
NAME
DOB
DEPT
ADDRESS

A contagem para o conjunto de dados 2 é: 5 e assim por diante para não dinâmica. de conjuntos de dados.

Eu quero a contagem de dados entre os campos START-OF-FIELDS & END-OF-FIELDS & para START-OF-DATA & FIM DOS DADOS. Qualquer corpo pode me dar um código exato para fazer isso? Eu usei

sed -n '/^START-OF-FIELDS/,/END-OF-FIELDS/{s/^START-OF-FIELDS//;/^END-OF-FIELDS/d;p;}' Sourcefile.txt > START_OF_FIELDS.TXT

wc -l START_OF_FIELDS.TXT

Mas não estou obtendo o resultado desejado.

    
por PVR 19.03.2013 / 10:32

4 respostas

2

Dada a nova descrição melhor do problema, isso é realmente mais fácil

#!/bin/bash
awk 'BEGIN {
            SETNR=0; 
            MODE="Non-Fields"}
(MODE=="Fields") && (! /START-OF-/ ) && (! /END-OF/ ) {
            print; 
            COUNT++
           }
/START-OF-FIELDS/ {
            COUNT=0; 
            SETNR++; 
            MODE="Fields"
           }
/END-OF/ {
            if (MODE=="Fields") {
                 printf ("Count for data set %d is: %d\n", SETNR, COUNT)
                };
            MODE="Non-Fields"
         }' $*
    
por 20.03.2013 / 09:30
0

Seu problema precisa ser melhor definido, mas olhando para sua entrada de exemplo, estou tentando adivinhar o que você quer fazer. Use um pequeno script AWK como este:

#!/bin/bash

awk '! /START-OF-/ {
  if (MODE=="DEFINE") { HEADER=HEADER $0 "|" }
  else if ((MODE=="DATA") && (NF>0)) { print }
}
 /START-OF-FIELDS/ { MODE="DEFINE"; HEADER="" }
 /START-OF-DATA/ {
      print HEADER
      MODE="DATA"
      HEADER=""
     }' | sed 's/|$//'

Isso produz:

ID|NAME|DEPT
1|joy|cs
2|sam|ec
ID |NAME|DOB|DEPT|ADDRESS
5|joe|13/2/2001/|ee|street1
3|gwen|4/08/1999|cs|street2

Nota: Eu sou preguiçoso, então adiciono uma barra vertical após cada campo no cabeçalho. Então eu uso o comando SED para remover as barras V posteriores.

    
por 19.03.2013 / 11:56
0
sed -n '/^START-OF-DATA$/,/^$/{/^START-OF-DATA$/d;/^$/d;p;}' filename

Isto é:

  • Colete as linhas entre START-OF-DATA e a próxima linha vazia - /^START-OF-DATA$/,/^$/ . Com essas linhas:
    • Exclua as linhas do delimitador - /^START-OF-DATA$/d e /^$/d
    • Imprima o restante - p
por 19.03.2013 / 13:46
0

Uma solução em awk :

$ awk '/END-OF/{flag=0;printf "Count for data set %d is: %d\n",++i,count;count=0;printf "\n"}
    {if(flag){
         count++;
         print;
     }}
    /START-OF/{flag=1}' file
ID
NAME
DEPT
Count for data set 1 is: 3

1|joy|cs
2|sam|ec
Count for data set 2 is: 2

ID 
NAME
DOB
DEPT
ADDRESS
Count for data set 3 is: 5

5|joe|13/2/2001/|ee|street1
3|gwen|4/08/1999|cs|street2
Count for data set 4 is: 2
    
por 03.05.2014 / 18:40