Линии счета, содержащие слово

Лучше всего использовать systemd; Однако я не знаю, доступно ли это в centos 6.5.

Без systemd: может быть проще запустить сценарий, который запускает и перезапускает ваш PHP-скрипт, вместо того, чтобы проверять его наличие. Примерно так:

#! /bin/bash
while ! php path/to/script/script_name; do
    :
done

При необходимости этот сценарий оболочки можно запустить с помощью nohup.

В общем, вам лучше использовать pgrep :

pgrep --full script_name
7
04.01.2019, 20:33
8 ответов

Другой вариант Perl, использующий List ::Util

$ perl -MList::Util=uniq -alne '
  map { $h{$_}++ } uniq @F }{ for $k (sort keys %h) {print "$k: $h{$k}"}
' file
0: 1
1: 1
2: 1
a: 1
different: 1
hello: 1
is: 3
man: 2
one: 1
possible: 1
the: 3
this: 1
world: 2
5
27.01.2020, 20:14

Это довольно простой -перл-скрипт:

#!/usr/bin/perl -w
use strict;

my %words = ();
while (<>) {
  chomp;
  my %linewords = ();
  map { $linewords{$_}=1 } split / /;
  foreach my $word (keys %linewords) {
    $words{$word}++;
  }
}

foreach my $word (sort keys %words) {
  print "$word:$words{$word}\n";
}

Основная идея состоит в том, чтобы зациклить ввод; для каждой строки, разбить ее на слова, затем сохранить эти слова в хэш (ассоциативный массив ), чтобы удалить любые дубликаты, затем перебрать этот массив слов и добавить единицу к общему счетчику для этого слова. В конце сообщите о словах и их количестве.

4
27.01.2020, 20:14

Прямолинейный -ish in bash:

declare -A wordcount
while read -ra words; do 
    # unique words on this line
    declare -A uniq
    for word in "${words[@]}"; do 
        uniq[$word]=1
    done
    # accumulate the words
    for word in "${!uniq[@]}"; do 
        ((wordcount[$word]++))
    done
    unset uniq
done < file

Просмотр данных:

$ declare -p wordcount
declare -A wordcount='([possible]="1" [one]="1" [different]="1" [this]="1" [a]="1" [hello]="1" [world]="2" [man]="2" [0]="1" [1]="1" [2]="1" [is]="3" [the]="3" )'

и форматирование по вашему желанию:

$ printf "%s\n" "${!wordcount[@]}" | sort | while read key; do echo "$key:${wordcount[$key]}"; done
0:1
1:1
2:1
a:1
different:1
hello:1
is:3
man:2
one:1
possible:1
the:3
this:1
world:2
5
27.01.2020, 20:14

Решение, вызывающее несколько программ из оболочки:

fmt -1 words.txt | sort -u | xargs -Ipattern sh -c 'echo "pattern:$(grep -cw pattern words.txt)"'

Небольшое пояснение:

fmt -1 words.txtвыводит все слова, по 1 на строку, а | sort -uсортирует этот вывод и извлекает из него только уникальные слова.

Чтобы подсчитать количество вхождений слова в файл, можно использоватьgrep(инструмент, предназначенный для поиска в файлах шаблонов ). Передав параметр -cw, grep выдает количество найденных совпадений слов. Таким образом, вы можете найти общее количество вхождений patternс помощью grep -cw pattern words.txt.

Инструмент xargsпозволяет нам делать это для каждого отдельного слова, выводимого sort. -Ipatternозначает, что он будет выполнять следующую команду несколько раз, заменяя каждое вхождение шаблона словом, которое он считывает из стандартного ввода, которое он получает из sort.

Косвенность с shнеобходима, потому что xargsзнает, как выполнить только одну программу с заданным именем, передавая ей все остальное в качестве аргументов. xargsне обрабатывает такие вещи, как подстановка команд. $(...)— это подстановка команды в приведенном выше фрагменте, поскольку она заменяет вывод grepна echo, что позволяет правильно отформатировать его. Поскольку нам нужна подстановка команд, мы должны использовать команду sh -c, которая запускает все, что она получает в качестве аргумента, в своей собственной оболочке.

2
27.01.2020, 20:14

Другой простой альтернативой может быть использование Python (>3.6 ). Это решение имеет ту же проблему, что и упомянутая @Larry в его комментарии .

from collections import Counter

with open("words.txt") as f:
    c = Counter(word for line in [line.strip().split() for line in f] for word in set(line))
    for word, occurrence in sorted(c.items()):
        print(f'{word}:{occurrence}')
        # for Python 2.7.x compatibility you can replace the above line with 
        # the following one:
        # print('{}:{}'.format(word, occurrence))

Более явная версия вышеизложенного:

from collections import Counter


FILENAME = "words.txt"


def find_unique_words():
    with open(FILENAME) as f:
        lines = [line.strip().split() for line in f]

    unique_words = Counter(word for line in lines for word in set(line))
    return sorted(unique_words.items())


def print_unique_words():
    unique_words = find_unique_words()
    for word, occurrence in unique_words:
        print(f'{word}:{occurrence}')


def main():
    print_unique_words()


if __name__ == '__main__':
    main()

Выход:

0:1
1:1
2:1
a:1
different:1
hello:1
is:3
man:2
one:1
possible:1
the:3
this:1
world:2

Вышеприведенное также предполагает, что words.txt находится в том же каталоге, что и script.py . Обратите внимание, что это не сильно отличается от других решений, представленных здесь, но, возможно, кому-то это покажется полезным.

2
27.01.2020, 20:14

Просто, хотя и не важно, будет ли он читать файл много раз:

sed 's/ /\n/g' file.txt | sort | uniq | while read -r word; do
  printf "%s:%d\n" "$word" "$(grep -Fw "$word" file.txt | wc -l)"
done

РЕДАКТИРОВАТЬ :Несмотря на преобразование пробелов в символы новой строки, при этом учитываются строки, в которых встречается каждое слово, а не сами слова. Это дает результат:

0:1
1:1
2:1
a:1
different:1
hello:1
is:3
man:2
one:1
possible:1
the:3
this:1
world:2

, который представляет собой символ -на символ -, идентичный результату примера OP.

0
27.01.2020, 20:14

Попытка сделать это с помощью awk:

count.awk:

#!/usr/bin/awk -f
# count line containing word

{
    for (i = 1 ; i <= NF ; i++) {
        word_in_a_line[$i] ++
        if (word_in_a_line[$i] == 1) {
            word_line_count[$i] ++
        }
    }

    delete word_in_a_line
}

END {
    for (word in word_line_count){
        printf "%s:%d\n",word,word_line_count[word]
    }
}

Запустите его:

$ awk -f count.awk./test.data | sort
0
27.01.2020, 20:14

Чистый ответ bash

echo "0 hello world the man is world
1 this is the world
2 a different man is the possible one" | while IFS=$'\n' read -r line; do echo $line | tr ' ' '\n' | sort -u; done | sort | uniq -c


   1 0
   1 1
   1 2
   1 a
   1 different
   1 hello
   3 is
   2 man
   1 one
   1 possible
   3 the
   1 this
   2 world

Я зациклил уникальные слова в каждой строке и передал ихuniq -c

редактировать :Я не видел ответа Гленна. Мне показалось странным не увидеть ответ bash

0
27.01.2020, 20:14

Теги

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