Лучше всего использовать systemd; Однако я не знаю, доступно ли это в centos 6.5.
Без systemd: может быть проще запустить сценарий, который запускает и перезапускает ваш PHP-скрипт, вместо того, чтобы проверять его наличие. Примерно так:
#! /bin/bash
while ! php path/to/script/script_name; do
:
done
При необходимости этот сценарий оболочки можно запустить с помощью nohup.
В общем, вам лучше использовать pgrep
:
pgrep --full script_name
Другой вариант 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
Это довольно простой -перл-скрипт:
#!/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";
}
Основная идея состоит в том, чтобы зациклить ввод; для каждой строки, разбить ее на слова, затем сохранить эти слова в хэш (ассоциативный массив ), чтобы удалить любые дубликаты, затем перебрать этот массив слов и добавить единицу к общему счетчику для этого слова. В конце сообщите о словах и их количестве.
Прямолинейный -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
Решение, вызывающее несколько программ из оболочки:
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
, которая запускает все, что она получает в качестве аргумента, в своей собственной оболочке.
Другой простой альтернативой может быть использование 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 . Обратите внимание, что это не сильно отличается от других решений, представленных здесь, но, возможно, кому-то это покажется полезным.
Просто, хотя и не важно, будет ли он читать файл много раз:
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.
Попытка сделать это с помощью 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
Чистый ответ 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