sed count lines between pattern - multiple files

Я не знаю математики для частоты, но мне нравится awk! Вот сценарий, который выполняет итерацию по каждой записи вашего тестового файла, выполняет умножение чисел и сравнивает их, чтобы увидеть, меньше ли они 5. Если меньше 5, не печатайте. В противном случае распечатайте.

#! / Usr / bin / awk -f НАЧАТЬ { print "ID V2 V3 V4 = PRODUCT"; } {{{1 }} TOTAL = int ($ 1 * $ 2 * $ 3); if (TOTAL <5) { # Не печатать } {{1} } else { напечатайте $ 1, "", $ 2, "", $ 3, "=", ИТОГО; } }

1
21.04.2017, 23:58
2 ответа
perl -lne '
   eof and !$a && print "$ARGV: ", 0+$a;          # no DONEs => ans=0
   next unless /DONE/ && !$a ... /DONE/;          # skip non-DONE ranges
   /DONE/ and !$a++ && next;                      # begin DONE range
   !/DONE/ and !eof and $a++,next;                # middle of DONE range
   !/DONE/ and eof and $a=2;                      # lone DONE => ans=0
   print "$ARGV: ", ($a-2, $a=0, close ARGV)[0];  # end of DONE range
                                                  # at the end we do 4 things: 1) subtract 2 from sum, 2) print filename+sum, 3) reset sum, and 4) skip the current file and jump to the next file in queue.
' ./*.txt

С помощью sed мы можем сделать это для отдельных файлов:

for f in ./*.txt; do
   printf '%s: %d\n' "$f" "$(sed -e '/DONE/,/DONE/!d; //d' "$f" | wc -l)"
done

Разница будет в сценарии, когда у нас не будет закрытия СДЕЛАНО.

0
27.01.2020, 23:33

Лучше используйте awk для count.

awk '
  FNR == 1 {inside = 0}
  $0 == "DONE" {
    if (inside) print FILENAME, n
    n = 0
    inside = ! inside
    next
  }
  inside {n++}' ./*.txt

Будет напечатана запись для каждого раздела DONE...DONE в каждом файле, что означает, что ничего не будет напечатано, если такого раздела нет. Чтобы напечатать 0 для них, вам понадобится реализация GNU awk с его специальными операторами BEGINFILE, ENDFILE:

awk '
  BEGINFILE {DONE_count = 0}
  $0 == "DONE" {
    if (++DONE_count % 2 == 0) print FILENAME, n
    n = 0
    next
  }
  DONE_count % 2 {n++}
  ENDFILE {if (!DONE_count) print FILENAME, 0}' ./*.txt

Или запустите один awk для каждого файла:

for file in ./*.txt; do
  awk '
    $0 == "DONE" {
      if (++DONE_count % 2 == 0) print FILENAME, n
      n = 0
      next
    }
    DONE_count % 2 {n++}
    END {if (!DONE_count) print FILENAME, 0}' "$file"
done
2
27.01.2020, 23:33

Теги

Похожие вопросы