Есть ли более элегантный способ подсчета слов и присвоение этому числу переменных?

У меня есть сценарий:

#!/bin/bash /root/xiotech status > xiostatus.tmp SyncCount=$(grep -c Sync xiostatus.tmp) PauseCount=$(grep -c paused xiostatus.tmp) CopyingCount=$(grep -c Copying xiostatus.tmp) if [ "$SyncCount" -eq "11" ] then echo All 11 mirrors are in sync. else echo $PauseCount mirrors are paused and $CopyingCount mirrors are syncing. fi rm -f xiostatus.tmp 

Есть ли более элегантный способ подсчета и «переменный-размер» этих счетчиков, используя что-то вроде awk? В этом случае файл крошечный, так что это не очень важно, но если файл был 900mb, потребуется 3 дополнительных цикла, чтобы пройти его 3 раза …

3 Solutions collect form web for “Есть ли более элегантный способ подсчета слов и присвоение этому числу переменных?”

awk может легко заменить весь скрипт:

 #!/usr/bin/awk -f /Sync/ {SyncCount++} /paused/ {PauseCount++} /Copying/ {CopyingCount++} END { if(SyncCount == 11) print "All 11 mirrors are in sync." else print (+PauseCount) " mirrors are paused and " (+CopyingCount) " mirrors are syncing." } 

(+var) – заставить awk обрабатывать переменную как число (поэтому она будет выводить 0 если переменная была отключена). Вы также можете использовать блок BEGIN чтобы сначала установить все переменные в 0 :

 BEGIN { SyncCount = PauseCount = CopyingCount = 0 } 

Вставьте файл в файл и запустите awk -f /path/to/the/script.awk xiostatus.tmp . Если вам не нужен временный файл, вы можете даже сделать /root/xiotech status | awk -f /path/to/the/script.awk /root/xiotech status | awk -f /path/to/the/script.awk .

Если вы установите бит выполнения на awk скрипте, вы можете назвать его автономным исполняемым файлом: /path/to/the/script.awk xiostatus.tmp или /root/xiotech status | /path/to/the/script.awk /root/xiotech status | /path/to/the/script.awk .

Для тех, кто хочет подсчитать все экземпляры, вот версия awk, которая будет считать несколько неперекрывающихся экземпляров, когда на одной строке больше одной

UPDATE: теперь я включил другой метод, который использует split(... .Это намного быстрее, чем match( substr(... метод match( substr(... ), который теперь указан ниже более быстрого. Метод split(... больше 4 раз быстрее, чем другие … (проверено на 87 файлов в общей сложности 407 612 строк.
Для дальнейшего сравнения метод Майкла Мрозека с использованием /Sync/ range-selection (который подсчитывает строки, контактирующие с каждым шаблоном, и подсчет всех экземпляров шаблона) в два раза быстрее, чем этот новый метод (для тех же данных).

Еще одно преимущество (?) Преимущества этого более быстрого split(methos) заключается в том, что он довольно терпим к недопустимым символам UTF-8 в файле (пока они не находятся в шаблоне разделителя) … Разделители сами являются фактической строкой шаблоны … Несколько из моих тестовых файлов имели в них недопустимый UTF-8, и мне потребовалось довольно много времени, чтобы узнать, почему у меня разные результаты от двух методов.
После того, как файлы проблем были перекодированы в действительный UTF-8, оба метода дают идентичные результаты.

Вот новый более быстрый метод (в 4 раза быстрее) … с помощью split(...

 #!/bin/bash pat='xx|yy|zz' awk -v vpat="$pat" 'BEGIN { split(vpat, pat, "|"); for(i in pat) pz++ } { if (NF) { for( p in pat ) { ct[p]+=(split( $0, A, pat[p] ) -1) }} } END { print " count pattern" for (p=1; p<=pz; p++) { printf "%6d %s\n", +ct[p], pat[p] } }' file 

Вот более медленный метод. используя match( substr(...

 #!/bin/bash # Count occurrences of multiple non-overlapping string patterns awk 'BEGIN { pattern[1]="xx" pattern[2]="yy" pattern[3]="zz" } { for( p in pattern ) { LHB=0; RSTART=RLENGTH=1 while( match( substr( $0, LHB+=(RSTART+RLENGTH-1)), pattern[p] )){ count[p]++ } } } END { print "occurs pattern" for (p in pattern) { printf "%6d %s\n", +count[p], pattern[p] } }' file 

Вот входной файл

 xx xx xx xx yy xx 

Вывод выглядит следующим образом:

 occurs pattern 5 xx 1 yy 0 zz 

Как насчет:

 eval `/root/xiotech status | grep -Eo 'Sync|paused|Copying' | sort | uniq -c | awk '{print "count_" $2 "=" $1}'` if [ "$count_Sync" -eq 11 ]; then echo All 11 mirrors are in sync. else echo $count_paused mirrors are paused and $count_Copying mirrors are syncing. fi 

grep -Eo позволяет искать несколько шаблонов (разделенных grep -Eo «|») и возвращает только строку, которая соответствует. sort | uniq -c sort | uniq -c показывает количество найденных слов. Скрипт awk форматирует новые команды оболочки для создания переменных, начинающихся с «count_». И, наконец, eval примет созданные команды оболочки и оценит их в оболочке.

  • Использование exec в поиске поверх ssh из сценария оболочки
  • Переменные в ksh
  • Удалить строку с пробелами и цитатами из xml-файла
  • Получение пустых данных при чтении текстового файла и отправка данных чтения в url cURL в linux
  • Переменная в Bash, содержащая кавычки и пробелы
  • Можно ли использовать команды типа `fg` в shell-скрипте?
  • Как я могу проанализировать ini-файл, чьи значения могут содержать определенные символы?
  • Найти и заменить с помощью sed с помощью подстановочных знаков при поиске и замене
  • Создание функции, отображающей имя переменной и ее значение
  • Как перенаправить вывод команды в файл?
  • Почему crontab работает с подстановочными знаками (*), но не с цифрами?
  • Interesting Posts

    скрипт запуска linux / etc / init с конкретным пользователем

    Sendmail с поддержкой поддержки TLS FROM: address

    Простейший способ хэширования паролей с несколькими различными алгоритмами хэша

    Данные перезаписываются с одинаковой отметкой времени в InfluxDB

    Как узнать, как долго мой симулятор запускается в UNIX?

    grep для строки без другой строки перед ней

    Жесткий диск часто вращается и поднимается слишком часто, когда аккумулятор

    Показывать определенные доли samba только некоторым пользователям

    Как выполнить запрос-замену после заданного символа в строке?

    Возможна условная / комбинированная команда sudoers?

    Задача Cron не запускается один раз в неделю

    Удаление обратных косых черт из текстового файла

    Домашний каталог vs Рабочий каталог

    Проверка в ksh, если каталог пуст

    Звук HDMI выходит из строя, решает, спустя несколько месяцев повторяет отказ (Intel NUC – монитор Viewsonic)

    Linux и Unix - лучшая ОС в мире.