sed를 사용하여 연속 스트리밍 출력을 조작하는 방법은 무엇입니까?


13

비 기술적 인 청중을위한 프레젠테이션을하고 있습니다. bash에서 실행중인 프로그램이있어 연속적인 값 스트림을 출력하며 그중 일부가 중요합니다. 관객이 자신의 빈도를 알 수 있도록 표시되는 중요한 결과를 강조하고 싶습니다. 문제는 sed실행중인 스트림에서 작동 할 수 없다는 것 입니다. 다음과 같이 결과를 파일에 넣으면 정상적으로 작동합니다.

cat output.txt | sed "s/some text/some text bolded/"

그러나 다음과 같이 실행중인 출력에서 ​​같은 것을 시도하면 :

command | sed "s/some text/some text bolded/"

sed아무것도하지 않습니다. 이견있는 사람?

Lambert가 지적하기에 충분히 도움이 되었기 때문에 sed아무 말도하지 않는 내 말 은 모호했습니다. 어떤 일이 일어나고은에 프로그램 출력이다 stdout(나는 확신이에 작성하지 않을거야 stderr)는 평소처럼, 그것은의를 통해 파이프하더라도 sed.

문제는 명령이 두 번째 프로그램을 호출하여 stdout으로 출력하는 것 같습니다. 첫 번째 프로그램이 인쇄 한 줄이 몇 개 있습니다. 이것들은 편집 할 수 있습니다. 그런 다음 두 번째 프로그램에 의해 인쇄 된 일련의 값이 있습니다. 이것들은 편집 할 수 없습니다.

Perl 및 awk 메소드는 작동하지 않습니다.


5
합니까의 stdbuf -o0 command | sed "s/some text/some text bolded/"작업?
FloHimself

3
'sed does not'은 대체가 이루어지지 않았거나 출력이 없다는 것을 의미합니까? 명령이 stdout 대신 stderr에 쓰는 중입니까? command|egrep 'some text|$'
Lambert에서

명령이 stdout에 쓰고 있습니까 (stderr가 아닌)?
Anthon

1
텍스트가 두 번 이상 나타나면 g"글로벌"대체를 추가해야합니다. 그렇지 않으면 행에서 처음 나타나는 것만 대체됩니다.sed "s/old/new/g"
ph0t0nix

@ ph0t0nix 아니오, 그것은 문제가 아니지만, 문제는 아닐 것입니다. 팁 고마워.
P Jones

답변:


12

명령의 출력이 버퍼링 될 가능성이 있습니다. 명령이 터미널에 쓰면 버퍼가 모든 줄 바꿈에서 플러시되므로 예상 속도로 표시됩니다. 명령이 파이프에 쓸 때 버퍼는 몇 킬로바이트에 도달 할 때만 플러시되므로 많이 지연됩니다. 표준 입 / 출력 라이브러리의 기본 동작입니다.

명령이 출력을 제한하지 않도록하려면 unbuffer(expect에서) 또는 stdbuf(GNU coreutils에서 ) 사용할 수 있습니다 .

unbuffer command | sed …
stdbuf -o0 command | sed …

stdbuf작동하지 않았습니다 (이전에 언급 한 BTW) unbuffer. 당신이 얼마나 행복했는지 몰라요
P Jones

간결한 설명에 감사드립니다. 매우 도움이됩니다.
P Jones

sed자체 (ChennyStar 포스트 CF)와 같은 버퍼, 여기에 예부터 작동하지 않을 수 있으므로 사용 sed은 IS command: 버퍼 해제에를 cat /etc/passwd | unbuffer sed하지만 sed자체가 가지고 -u있으므로, 옵션 grep이 예에서 더 suiteable 수 있습니다. 당신의 배경 정보를 주셔서 감사합니다! 좋은 대답입니다!
math

4

sed 그 옵션이 있습니다 :

-u,-언 버퍼

입력 파일에서 최소량의 데이터를로드하고 출력 버퍼를 더 자주 플러시합니다. 자세한 내용 man sed은 참조하십시오.


1
GNU sed만 (BSD sed아님), 나는 이것이 파이프 시작시 명령의 버퍼링을 여전히 막지 못할 것이라고 생각합니다. 그러나 언급하는 것이 좋습니다. :)
와일드 카드

stdbuf 맨 페이지는 "COMMAND가 표준 스트림의 버퍼링을 조정하면 (예를 들어 'tee'가 수행하는 경우) 'stdbuf'에 의해 해당 변경 사항을 무시합니다." sed가이 범주에 속할 것 같지만 '-u'플래그는 버퍼되지 않은 파이프 체인에서 유용합니다.
MattSmith

2

나는 awk를 사용할 것이다

  command | awk '/some important stuff/ { printf "%c[31m%s%c[0m\n",27,$0,27 ; next }
  { print ; } '

어디

  • /some important stuff/ sed에서와 같이 중요한 라인을 선택하십시오
  • printf "%c[31m%s%c[0m\n",27,$0,27 ; 빨간색으로 인쇄
    • 녹색, 노란색에는 32,33을 사용하십시오 ...
    • $ 1, $ 2는 특정 필드를 선택하는 데 사용할 수 있습니다
  • 다른 줄은 '있는 그대로'인쇄됩니다

요점은 command라인을 플러시해야하지만 출력이 많은 경우에 해당됩니다.


참고 :이 질문은 전체 줄이 "굵게"되어야하지만 "일부 텍스트"여야한다고 말합니다. 또한, 그 기능의 구현이 가능하면서 awk(사용 sub()또는 gsub()) 프리미티브 교체시 sed확실히 적절한 도구이다.
Janis

1

펄 방식 :

command | perl -pe 's/(stuff)/\x1b[1m$1\x1b[0m/g'

또는 지속적인 출력으로 :

출력을위한 bash 스크립트 cont:

#!/bin/bash
while [ true ]
do
   echo "Some stuff"
done

다음을 사용하여 테스트하십시오.

./cont | perl -pe 's/(stuff)/\x1b[1m${1}\x1b[0m/g'
  • \x1b[1m -대담하거나 증가 된 강도
  • ${1} -역 참조
  • \x1b[0m -모든 속성을 재설정

산출:

어떤 물건
어떤 물건
어떤 물건
어떤 물건

더 많은 이스케이프 코드는 여기에 있습니다 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.