awk -шаблон подсчета во всем столбце

Вы можете установить эти свойства в своем Vagrantfile, чтобы указать URL-адрес:

config.vm.box = "centos7"
config.vm.box_url = "http://myserver.mydom.om/centos7"

Если это локальный файл в вашей системе, где вы работаетеvagrant:

config.vm.box = "centos7"
config.vm.box_url = "file:///tmp/centos7"

Если вы используете Windows:

config.vm.box = "centos7"
config.vm.box_url = "file:///C:/tmp/centos7"
4
04.08.2020, 17:42
6 ответов

«Безопасный» подход :мы не предполагаем, что поле без «E» в начале автоматически является значением поля, которое вы хотите (в вашем примере :игнорируя «Заголовок2», есть только 1 другое значение, а может в вашем реальном файле может быть больше?)

Допустим, awk :использует "," в качестве разделителя, подсчитывает появление каждого значения поля 2 и печатает их в конце:

awk -F',' '
/Header2/ { rem="This is a title line, we skip it..." ; next ;}
          { nbseen[$2]++ }
END       { for(value in nbseen) {
               printf("%-20s : %6d\n",value,nbseen[value]) 
             } 
           }
' FinalOutput.csv | sort

Это будет отображать, отсортированные по алфавиту, все значения, видимые во 2-м столбце, и их количество вхождений, и игнорирует «строки заголовков» (, будь они в 1-й строке или даже если они повторяются время от времени.)

Это покажет:

DBFXFR                   : 4
EBFXFR                   : 1

(затем вы можете "grep -v -E 'this|that'", чтобы игнорировать строки с "this" или "that" (ex :grep -Ev "^E", и увидит все значения, которые не начинаются с «E», и их вхождения)

Если вы уверены, что любая строка, не начинающаяся с буквы «Е», является правильным значением и, следовательно, ее нужно просто сложить вместе, вы можете использовать менее общий вариант:

awk -F',' '
/Header2/ { next }
/^[^E]/   { count++ }
END       { print count + 0 }

'

0
18.03.2021, 23:15

Вы очень близки, awk -F, 'NR>1{if ($2 !~ /^E/){count++}} END {print count}'должно сработать.

-F,сообщает awk, что ,является разделителем

NR>1снимает заголовок

Я выполнил это на вашем образце файла, и он выдал правильный результат

4
18.03.2021, 23:15

У вашей команды awkесть несколько проблем.

  • Вы не указали разделитель полей, поэтому awkразделяет строки по пробелу, а не ,. Вы можете использовать опцию строки команды -F','-, чтобы установить разделитель полей.
  • Ваше регулярное выражение указывает /^E_/и, следовательно, будет искать поля, которые не начинаются с E_(, которых нет ни в одном из ваших значений столбца 2 ), , а не , а только те, которые не начинаются с E. Удалите _.
  • Ваша команда также будет считать строку заголовка. Вы можете использовать внутреннюю переменную FNR(, которая автоматически устанавливается на текущий номер строки в текущем файле ), чтобы исключить первую строку.
  • Как заметил Ракеш Шарма, если все строки начинаются с E,команда будет печатать пустую строку в конце вместо 0из-за использования неинициализированной переменной. Вы можете принудительно интерпретировать как число, напечатав count+0вместо count.

Исправленная версия будет

awk -F',' 'FNR>1 && $2!~/^E/{count++} END{print count+0}' FinalOutput.csv

Обратите внимание: поскольку я использовал FNRна -строку файла -счетчик (, а не глобальную строку -счетчик NR), это также будет работать с более чем одним входным файлом, где все из них есть строка заголовка, т.е. вы даже можете использовать ее как

awk -F',' '... ' FinalOutput1.csv FinalOutput2.csv...
6
18.03.2021, 23:15

Некоторые другие подходы:

  • awkпо умолчанию печатает, если условие истинно, поэтому вы можете просто выполнить:

    $ awk -F, 'NR>1 && $2!~/^E/' file | wc -l
    4
    
  • распечатайте файл, начиная со второй строки, и подсчитайте, сколько раз вы видите запятую, за которой следует не -символ E (обратите внимание, что это предполагает только одну запятую в строке, как показано в вашем примере):

    $ tail -n+2 file | grep -c ',[^E]'
    4
    
  • perl

    $ perl -F, -lane '$c++ if $.>1 && $F[1] !~ /^E/ }{ print $c' file
    4
    
  • sedиwc

    $ sed -n '1d; /,[^E]/p' file | wc -l
    4
    
5
18.03.2021, 23:15

Питон

#!/usr/bin/python
import re
j=re.compile(r'^E')
r=[]
k=open('file','r')

k.readline()
for i in k:
    m=i.strip().split(",")
    if not re.search(j,m[1]):
        r.append(i.strip())
print len(r)

awk и sed

sed -e  '1d' -n -e '/,E/!p' file| awk 'END{print NR}'
4
1
18.03.2021, 23:15

awk с глотанием всего файла (так, что NR равно 1)

$ awk -F '\n[^\n]*,[^E]' '{ print NF-1 }' RS='^$' file
4

GNU grep в режиме PCRE

$ < grep -zoP '\n.*\K,[^E]'  | xargs -r0 -n1 | wc -l
4

perl в режиме slurp

$ perl -F'\n.*,[^E]' -pal -0777e '$_=$#F' file 
4

POSIX grep /head

$ { head -n 1 > /dev/null; grep -c ',[^E]'; } < file
4

GNU sed в расширенном режиме регулярных выражений

$ sed -Ee "
    1d;/,[^E]/{z;H;}
    \$!d;g;y/\n/d/
    :a
      s/d{10}/#/g
      s/#([0-9]*)$/#0\1/
      $(seq 9 -1 1 | xargs -I {} printf 's/d{%d}/%d/;' {} {})
      y/#/d/
    ta
    s/^\$/0/
" file
4
1
18.03.2021, 23:15

Теги

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