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
То есть часть подстановки говорит: «В первом пробеле -косая черта -косая черта, с которой мы сталкиваемся, удаляет ее и все, что следует за ней, оставляя любой предшествующий текст в покое».
Этого можно добиться с помощью следующего скрипта, учитывая, что 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
, мы можем, наконец, убить процесс, когда нужная строка будет напечатана.