Существует ли более изящный способ считать слова и присвоить то количество переменным?

В Gnome Ubuntu недавние документы хранятся в ~/.recently-used.xbel. Вы можете rm тот файл, но Панель Gnome все еще покажет список. Там получен, чтобы быть лучшим способом заставить панель обновляться, но killall gnome-panel будет работать.

rm ~/.recently-used.xbel
killall gnome-panel
5
08.02.2012, 02:48
3 ответа

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 если переменная была сброшена). Можно также использовать a 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.

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

13
27.01.2020, 20:31
  • 1
    Работы, если существует только один экземпляр строк поиска на строку. –  Arcege 08.02.2012, 03:06
  • 2
    @Arcege Правда, я принял. Я не знаю, существует ли очевидный способ для соответствия тому же шаблону многократно на строку; я думаю, что большинство людей делает ужасный match()/substr() обман –  Michael Mrozek♦ 08.02.2012, 03:12
  • 3
    На строку существует только один. Существует ли способ присвоить 0 значениям, которые не возвращены? печать ничего не распечатает, если значение будет нулевым, я предполагаю.... –  LVLAaron 08.02.2012, 03:52
  • 4
    @LVLAaron можно использовать a BEGIN блок; я добавил его к –  Michael Mrozek♦ 08.02.2012, 03:56
  • 5
    Вы не должны инициализировать Вар в BEGIN если Вы вынуждаете их распечатать как числа и не, поскольку (значение по умолчанию) представляет в виде строки — просто помещает знак "плюс" перед каждым var и переносят его в скобках (это неправильно себя ведет плохо с print если Вы не используете скобки) — awk 'END{neg=-1; pos=+1; printf "%d %d %d", +neg, +pos, +uninit; print " |", (+neg), (+pos), (+uninit)}' /dev/null — выводы: -1 1 0 | -1 1 0 –  Peter.O 08.02.2012, 07:21

Как насчет:

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 допускает поиск нескольких шаблонов (разделенный "|") и возвращает только строку, которая соответствовала. sort | uniq -c показывает количество найденных слов. awk форматы сценария новая оболочка управляют для создания переменных, запускающихся с "количества _". И наконец, eval возьмет созданные команды оболочки и оценит их в оболочке.

3
27.01.2020, 20:31
  • 1
    Это не работает. Это добавляет все до 11 каждых раз, каковы строки. –  LVLAaron 08.02.2012, 03:53
  • 2
    @LVLAaron ответа Действительно? Это работает на меня, хотя это имеет ту же проблему, мой ответ имел (пустые строки вместо 0s, если критерий поиска не появляется), –  Michael Mrozek♦ 08.02.2012, 03:59
  • 3
    @Arcege: +1 Это - молния быстро! в в 5-6 раз быстрее, чем самый близкий соперник (Michaek Mrozek, которому я верю, можно настроить для удвоения его скорости)... Этому просто нужен некоторый другой метод обработки шаблонов, которые не найдены... Существует всего одна вещь об этом, которая препятствует тому, чтобы это было общим purposs.. Это соответствует первому шаблону, это находит и затем продолжает поиск после того соответствия.. Это работает на спецификации вопроса, но это означает, что из-за наложения, "beware|will|miss|are" и другие такие перекрывающиеся шаблоны –  Peter.O 09.02.2012, 05:39

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

ОБНОВЛЕНИЕ: Я теперь включал другой метод, который использует split(.... Это намного быстрее, чем match( substr(... метод, который теперь упоминается ниже более быстрый. split(... метод больше чем в 4 раза быстрее, чем другой... (протестированный на 87 файлах на в общей сложности 407 612 строк.
Для дальнейшего сравнения, метода Michael Mrozek, с помощью /Sync/ выбор диапазона (который считает строки containg каждым шаблоном по сравнению с подсчетом всех экземпляров шаблона) дважды с такой скоростью, как этот новый метод (для тех же данных).

Другое преимущество края (?) этого быстрее 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
4
27.01.2020, 20:31

Теги

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