Найти 10 «main ()» в первых 10 строках в обычных файлах

Как l0b0 упомянул в своем ответе, файл crontab указывает только время запуска заданий. Ему все равно, если задание выполняется часами, и он с радостью запустит его снова, когда наступит следующее время запуска, даже если предыдущее воплощение задания все еще выполняется.

Судя по вашему описанию, вы хотите, чтобы задача B запускалась, если задача A выполняется слишком долго.

Вы можете добиться этого, объединив две задачи в один и тот же скрипт:

#!/bin/sh

timeout=600     # time before task B is started
lockfile=$(mktemp)
trap 'rm -f "$lockfile"' EXIT INT TERM QUIT

# Start task A
# A "lock file" is created to signal that the task is still running.
# It is deleted once the task has finished.

( touch "$lockfile" && start_task_A; rm -f "$lockfile" ) &
task_A_pid="$!"

sleep 1     # allow task A to start

# If task A started, sleep and then check whether the "lock file" exists.
if [ -f "$lockfile" ]; then
    sleep "$timeout"

    if [ -f "$lockfile" ]; then
        # This is task B.
        # In this case, task B's task is to kill task A (because it's
        # been running for too long).
        kill "$task_A_pid"
    fi
fi

0
28.06.2017, 13:17
3 ответа

Вы также можете воспользоваться GNU grep с его регулярными выражениями Perl. Это выведет строку, содержащую строку main ()в любом месте первых 10 строк входного файла.

Опция -zпозволяет обрабатывать файл как одну большую строку (, если она не содержит символов NUL ), с которыми должен работать grep. -Pвключает Perl-режим grep, -oпоказывает совпадающую часть, -hскрывает имя файла от отображения рядом с соответствующей строкой, а -lотображает только имя файла.

Если вам нужно и имя файла, и соответствующая строка:

grep -HPoz  '\A(.*\n){0,9}\K[^\n]*main\(\)[^\n]*\n' file.txt

только совпадающая строка:

grep -hPoz '\A(.*\n){0,9}\K[^\n]*main\(\)[^\n]*\n' file.txt

(-hнеобходимо только при наличии более одного файла)

только имя файла:

grep -Pozl '\A(.*\n){0,9}\K[^\n]*main\(\)[^\n]*\n' file.txt

Чтобы запустить текущий каталог, но без рекурсии:(ofc, параметры grep должны быть предоставлены в соответствии с требованиями, как показано выше)

find. ! -name. -prune -type f \
  -exec grep -HPoz '\A(.*\n){0,9}\K[^\n]*main\(\)[^\n]*\n' {} +
1
28.01.2020, 02:25

Я бы использовал awk:

awk 'FNR <= 10 && index($0, "main()") {print FILENAME ":", $0}' ./*.c
1
28.01.2020, 02:25

Если вы хотите найти шаблон в первых десяти строках нескольких файлов, вы можете:

for file in *; do 
    head -n 10 "$file" | grep -F 'main()' 
done

Это напечатает совпадающие строки. Чтобы напечатать совпадающую строку и имя файла, используйте:

for file in *; do 
    q=$(head -n 10 "$file" | grep -F 'main()')
    [ -z "$q" ] || printf '%s : %s\n' "$file" "$q"
done

И печатать только имена файлов, а не соответствующую строку:

for file in *; do 
    head -n 10 "$file" | grep -qF 'main()' && printf '%s\n' "$file" 
done
1
28.01.2020, 02:25

Теги

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