Завершить процесс при определенном выходе

sed -e '/^\/\//d' -e 's@\(.*\)[[:blank:]]\{1,\}//.*@\1@' your_file

Эта команда sed удаляет строки, начинающиеся с комментария, а для встроенных комментариев она удаляет все, начиная с пробела, отделяющего код от комментария, до конца строки. Это POSIX (без использования расширений GNU )и, согласно исходному примеру OP и для простоты чтения, эта версия поддерживает только //комментарии (, подробнее об этом ниже ).

Детали

Этот вызов sedвключает две команды sed :«удалить при совпадении с шаблоном» и замену.

Первый — /^\/\//d. Шаблон ^\/\/соответствует строкам, начинающимся с двух косых черт (, например. "// foo bar" ). Такие строки удаляются и сразу вставляется следующая строка (т.е. подстановка пропускается ).

Шаблон в замене \(.*\)[[:blank:]]\{1,\}//.*. Примечание. :Я использую @в качестве разделителя, чтобы избежать экранирования некоторых символов, которые требуются для разделителя /.

  • \(...\)- все, что соответствует внутри, доступно в качестве обратной ссылки
  • .*-соответствует 0 или более символов (что угодно, кроме новой строки ); в разделе подстановки мы можем вернуться к тому, что соответствует здесь, из-за окружения \(и \).
  • [[:blank:]]-пробел
  • \{1,\}-соответствует одному или нескольким предшествующим элементам([[:blank:]]в данном случае)
  • //-соответствует двум косым чертам (, то есть началу комментария)
  • .*-То же, что и выше, за исключением того, что недоступно в качестве обратной ссылки

Часть подстановки — это просто \1, которая говорит заменить все, что мы сопоставили с первой обратной ссылкой, то есть .*, которая предшествовала [[:blank:]].

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

' #' Комментарии

В GNU sed добавление обработки комментариев #— это всего лишь вопрос замены //чередованием(#|//)(или необходимости экранирования\(#\|\/\/\)). Однако способ POSIX гораздо более подробный, потому что чередование не поддерживается. Очевидно, вы могли бы переборщить, повторив существующие команды sed с версиями для #. Еще лучше, что уже опубликован ответ, который показывает более чистый способ сделать это. В любом случае я не буду повторять решение здесь.

РЕДАКТИРОВАТЬ:

Вернувшись к этому спустя много времени, я понял, что замена более сложна, чем должна быть, и, как указано в комментариях, не улавливает некоторые угловые случаи, кроме (, например. "что-то // foo // bar".. удалено только "// bar" ).

Думаю, это все, что нам нужно...

sed -e '/^\/\//d' -e 's@[[:blank:]]\{1,\}//.*@@' your_file

То есть часть подстановки говорит: «В первом пробеле -косая черта -косая черта, с которой мы сталкиваемся, удаляет ее и все, что следует за ней, оставляя любой предшествующий текст в покое».

0
25.11.2019, 19:25
2 ответа

Этого можно добиться с помощью следующего скрипта, учитывая, что grep -m1у вас не работает:

#!/bin/bash

java -jar xyz.jar &> "/tmp/yourscriptlog.txt" &
processnumber=$!
tail -F "/tmp/yourscriptlog.txt" | awk  '/Started server on port 8000/ { system("kill '$processnumber'") }'

По сути, этот скрипт перенаправляет stdoutвашего java-кода в файл с помощью команды &> "/tmp/yourscriptlog.txt", последняя &в первой строке заставляет ваш код выполняться как изолированный процесс, а в следующей строке у нас есть номер этого процесса с $!. Имея номер процесса и файл журнала в tail, мы можем, наконец, убить процесс, когда нужная строка будет напечатана.

1
28.01.2020, 02:29
java -jar xyz.jar | grep -m1 "Started server on port 8000"
1
28.01.2020, 02:29

Теги

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