Как получить количество данных между двумя строками с несколькими вхождениями в одном файле

У меня есть данные в моем файле как

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 

ОЖИДАЕМЫЙ ВЫХОД: –

 ID NAME DEPT 

Количество для набора данных 1: 3

 ID NAME DOB DEPT ADDRESS 

Счет для набора данных 2 равен: 5 и так далее для динамического номера. наборов данных.

Я хочу подсчитывать данные как между СТАРТ-ПОЛЯМИ И КОНЕЧНЫМИ ПОЛЯМИ, так и для ПУНКТА ДАННЫХ И КОНЕЦ ДАННЫХ. может ли любой орган дать мне точный код, чтобы сделать это. я использовал

 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 

Но я не получаю желаемого результата.

  • Проверьте, является ли условие awk совпадением в лог-файле
  • Прочитайте строку из файла, манипулируйте, а затем добавьте в другой файл
  • Выбор случайной выборки из дерева каталогов
  • Создание переменной с sed в ksh
  • Сценарий оболочки для удаления нескольких файлов
  • Печать эха в файле и запрос параллельно
  • Сценарий для поиска среды рабочего стола по умолчанию?
  • Объедините две команды в .bash_profile
  • 4 Solutions collect form web for “Как получить количество данных между двумя строками с несколькими вхождениями в одном файле”

    Учитывая новое лучшее описание проблемы, это на самом деле проще

     #!/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" }' $* 

    Ваша проблема должна быть лучше определена, но, глядя на ваш образец ввода, я делаю догадки о том, что вы хотите сделать. Используйте небольшой AWK-скрипт следующим образом:

     #!/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/|$//' 

    Это дает:

     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 

    Примечание. Я ленив, поэтому добавляю вертикальную панель после каждого поля в заголовке. Затем я использую команду SED для последующего удаления конечных V-баров.

     sed -n '/^START-OF-DATA$/,/^$/{/^START-OF-DATA$/d;/^$/d;p;}' filename 

    То есть:

    • Соберите строки между START-OF-DATA и следующей пустой строкой – /^START-OF-DATA$/,/^$/ . С этими линиями:
      • Удалить разделительные линии – /^START-OF-DATA$/d и /^$/d
      • Распечатайте остальные – p

    Решение в 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 
    Linux и Unix - лучшая ОС в мире.