2010-11-23 5 views
7

나는 fd3에 쓰는 프로그램을 가지고 있고 그 데이터를 grep과 sed로 처리하려고한다. 다음 코드는 지금까지 모습입니다 : 내가 예상대로 내가 그런 다음sed를 버퍼링하는 것을 멈추는 방법?

exec 3>&-

할 때까지


exec 3> >(grep "good:"|sed -u "s/.*:\(.*\)/I got: \1/") 
echo "bad:data1">&3 
echo "good:data2">&3 

아무것도 출력되지 않습니다, 내가 원하는 모든 것을 마침내 도착 :

 
I got: data2 

grep 또는 sed 만 사용하면 즉시 회신하는 것처럼 보이지만 혼합하면 버퍼링이 발생하는 것 같습니다. fd3에서 즉시 출력을 얻으려면 어떻게해야합니까?

답변

3

대체는 당신에게를 제공한다는 것입니다 아마

BEGIN { $| = 1 } 

이 작업을 수행하는 다른 이유처럼, 버퍼링에서 sed 명령 버퍼를 가지고 the s2p sed-to-Perl translator를 통해 실행하고 지시를 삽입하는 것입니다 중지하는 것을 의미한다 백 슬래시 성가신 레거시 BRE 대신 ERE에서 더 편리하게 표기 할 수 있습니다. 또한 종종 중요한 Unicode 속성을 완벽하게 보완합니다.

그러나 간단한 sed 명령에는 변환기가 필요하지 않습니다. 그리고 grepsed도 필요하지 않습니다. 이러한 모든 작업 :

perl -nle 'BEGIN{$|=1} if (/good:/) { s/.*:(.*)/I got: $1/; print }' 

perl -nle 'BEGIN{$|=1} next unless /good:/; s/.*:(.*)/I got: $1/; print' 

perl -nle 'BEGIN{$|=1} next unless /good:/; s/.*:/I got: /; print' 

지금 당신은 또한 최소한의 정량, *?, +?, ??, {N,}?{N,M}?에 액세스 할 수 있습니다. 이제는 .*? 또는 \S+? 또는 [\p{Pd}.]??과 같은 것을 허용합니다.

+0

나는 당신이 추천 한대로 실제로 펄 루트를 갔다. 나는 bash 스크립트에서 유용성을 알지 못했다. perl과 bash는 확실히 잘 어울립니다. – User1

6

나는 그것을 발견했다고 생각한다. 어떤 이유로 grep은 자동으로 회선 버퍼링을 수행하지 않습니다. grep--line-buffered 옵션을 추가했는데 즉시 응답합니다.

+1

'grep'는 거대한 파일이나 거대한 파이프 스트림을 제공 할 것으로 예상됩니다. 이러한 경우 완충 효과가 훨씬 더 효율적입니다. (리눅스를 사용하게 된 것을 기쁘게 생각합니다.이 OSX 컴퓨터에는 grep 또는 sed에 대한 라인 버퍼링 옵션이 없습니다.) – zwol

+2

와우. OSX 머신에 대해 유감입니다. OSX가 실제로 돈을 버는 것은 더욱 유감입니다. 적은 기능, 더 많은 돈, 애플은 어떻게 그걸 해 냈습니까? – User1

+0

OSX는 * 커맨드 라인 해킹을위한 것이 아닙니다. 그들이 BSD 토대를 유지했기 때문에 기쁩니다. 그러나이 컴퓨터에서는 CLI가 아닌 것에 더 많은 시간을 할애합니다. – zwol

3

당신은 너무처럼 sedgrep을 병합 할 수 있습니다 : 당신은 단지에 적용 할 수있는 SED 명령을하기 전에 (평소와 같이 슬래시 사이) 정규 표현식을 넣을 수 있습니다 :

exec 3> >(sed -une '/^good:/s//I got: /p') 
echo "bad:data1">&3 
echo "good:data2">&3 

는 조금 것을 풀기 해당 정규 표현식과 일치하는 행. s 명령에 대한 첫 번째 정규식 인수가 빈 문자열 ( s//whatever/)이면 일치하는 마지막 정규식 (이 경우 접두어)을 다시 사용하므로 반복하지 않아도됩니다. 그리고 마지막으로 -n 옵션을 사용하면 sed에게 인쇄 할 내용 만 인쇄하도록 지시하고 s 명령의 접미어 /p은 대체 결과를 인쇄하도록 지시합니다.

-e 옵션은 꼭 필요한 것은 아니지만 좋은 스타일이며 "다음 인수는 파일 이름이 아닌 sed 스크립트"를 의미합니다. 작은 따옴표

항상 넣어 SED 스크립트는 당신이 거기에 쉘 변수를 대체 할 필요가없는, 심지어 나는 모든 것을 하지만에게 작은 따옴표로 쉘 변수를 (쉘 변수는 물론, 둘 것, 더블 인용). 그렇게 백 슬래시와 관련된 슬픔을 피할 수 있습니다.

+0

멋진 정보 - 나는 * 모든 것을 알고 익숙해졌습니다! –

+0

sed, awk, grep, perl.. 모두 매우 강력합니다. 나는 그것들 모두를 배우기위한 대역폭이 없기 때문에 그것은 단지 하나의 유틸리티 였으면 좋겠다. – User1

+0

올바른 방법은/bin/sh + "coreutils"의 모든 것이 여러 실행 파일로 나뉘는 유틸리티 중 하나라는 점입니다. Awk와 perl은 그들 자신의 것이지만 솔직히 요즘은 awk를 배우는 것이 귀찮을 것 같지 않습니다. perl은 엄격하게 더 좋기 때문에 특히 명령 행 옵션을 배우면 더욱 그렇습니다. (당신은 perl을 가지고 있지 않은 시스템에 대해 걱정할 필요가 있었지만 더 이상 관련이 없다고 생각합니다.) 또한이 영역에서 중요한 기술은 쉘을 포기하고 모든 것을 위해 펄이나 파이썬을 사용해야 할 때를 아는 것입니다 대신. – zwol

1

Mac의 경우 brew install coreutils을 사용하고 gstdbuf를 사용하여 grep 및 sed의 버퍼링을 제어하십시오.

+1

JFTR, 그냥 GNU/Linux 시스템에서'stdbuf '입니다. – kostix

관련 문제