Как вывести каждый N-й символ строки?

crontab -e

# min hr day month day_of_week

# every minute run :
1 * * * *   /root/watch_processes.sh

один раз вручную:mkdir /root/process_watch

создать простой скрипт/root/watch_processes.sh

#!/bin/bash

#       %cpu    pid   command    args

ps -eo   "%C %P %U %c %a" > /root/process_watch/`date +%Y%m%d_%H%M`

Приведенное выше будет создавать текстовый файл каждую минуту, имеющий только дату в качестве имени файла, но все они будут находиться в заданной папке, которая в приведенном выше примере — /mkdir/process_watch. Отрегулируйте соответствующим образом.

http://linuxcommand.org/lc3_man_pages/ps1.html

при необходимости настройте вывод ps -eoдля каждого процесса, использование %C %P %U %c %aприведет к этим 5 столбцам данных

  1. процессор %
  2. идентификатор процесса
  3. имя пользователя
  4. выполняется команда
  5. аргументы для запуска команды

В каждом файле вы получите много листинга с 0.0 в первом столбце. Кто-то, хорошо разбирающийся в awkили sed, может добавить синтаксис к приведенному выше, чтобы отфильтровать процессы с 0% процессора.

как было сказано, вы должны перехватывать процесс, когда он происходит, после завершения процесса нет записи о том, что pid #занял %cpu, когда. Вам нужно будет выполнить просмотр процесса таким образом, а затем вернуться и найти нарушителей.

1
05.10.2020, 17:55
5 ответов

Довольно просто сделать в оболочке:

letters='' word=1234567890abcdefghijklmnopqrstuvwxy
for ((i=0; i<${#word}; i+=8)); do letters+=${word:i:1}; done
echo "$letters"  # => 19gow
3
20.08.2021, 10:40
echo 1234567890abcdefghijklmnopqrstuvwxy | sed 's/\(.\{0,1\}\).\{1,7\}/\1/g'
19gow

Оригинал делал:

s/               substitute
.\{1,7\}         upto 7 characters
\(.\{0,1\}\)     and then the next in a capture
/                replace by
\1               that what was captured
/g               globally, so as many times as possible

Таким образом, перемещение группы захвата вперед, а не в конец делает именно то, что вы просили.

s/               substitute
\(.\{0,1\}\)     capture the first character
.\{1,7\}         match upto 7 characters
/                replace by
\1               that what was captured
/g               globally, so as many times as possible
3
20.08.2021, 10:40

На самом деле вы не объясняете, что вам нужно, но один из способов получить желаемый результат — выбрать каждый 8-й символ. Что-то вроде этого:

$ echo 1234567890abcdefghijklmnopqrstuvwxy | sed -E 's/(.).{0,7}/\1/g'
19gow

Эта подстановка ищет и "захватывает" любой символ ((.)), затем заменяет его и следующие 7 символов (или меньше, если осталось менее 7 символов )с самим собой. По сути, это удаляет все, кроме каждого 8-го -го символа.

7
20.08.2021, 10:40

С awk:

str="1234567890abcdefghijklmnopqrstuvwxy"
awk '{for (i=1;i<=length;i=i+8) printf substr($0,i,1); printf "\n"}' <<< "$str"
19gow
1
20.08.2021, 10:40

Сzsh:

$ set -o extendedglob # best in ~/.zshrc
$ string=1234567890abcdefghijklmnopqrstuvwxy
$ print -r -- ${string//(#b)(?)?(#c,7)/$match[1]}
19gow

Сksh93:

$ string=1234567890abcdefghijklmnopqrstuvwxy
$ print -r -- "${string//@(?){,7}(?)/\1}"
19gow

bash, как и zsh, скопировал ${var//pattern/replacement}из ksh93 и несколько расширенных глобальных операторов ksh, включая @(...), но не {x,y}(...)и обратную ссылку -в замене.

Они должны работать независимо от того, какой символ $stringможет содержаться, даже символ новой строки.

Эквивалент POSIX:

awk '
  BEGIN {
    len = length(string = ARGV[1])
    for (i = 1; i <= len; i += 8) result = result substr(string, i, 1)
    print result
  }' "$string"
4
20.08.2021, 10:40

Теги

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