awk를 사용하여 grep 출력 형식을 지정합니다. 단순 사례 및 배경 사례

awk를 사용하여 grep 출력 형식을 지정합니다. 단순 사례 및 배경 사례

나는 이 문제를 해결하려고 노력하고 있습니다. 나는 다음 줄을 가지고 있습니다 :

mplayer *.* 2>/dev/null | grep Playing

방금 시작되었고 mplayer일치하는 줄만 화면에 인쇄되었습니다. 이는 현재 재생 중인 미디어를 변경할 때마다 작동합니다.Playing filename

grep 의 출력을 "형식화"하는 것이 가능한지 궁금합니다. 예를 들어 출력이 다음과 같은 경우:

Playing Pink_Floyd-Wish_You_Were_Here.mp3  # I get this at the beginning
Playing Pearl_Jam-Once.mp3                 # I get this after I change media inside mplayer

그러면 나는 다음과 같은 것을 갖게 될 것입니다 :

Mplayer: Playing Pink_Floyd-Wish_You_Were_Here.mp3
Mplayer: Playing Pearl_Jam-Once.mp3

이를 위해 awk를 사용하기로 결정했습니다.

mplayer *.* 2>/dev/null | grep Playing | awk '{print "Mplayer: "$1}'

하지만 이 경우에는 아무 일도 일어나지 않습니다.

내 질문은 mplayer의 문제를 해결하기 위한 것이 아니라 bash의 파이프에 대한 더 깊은 이해를 얻기 위한 것입니다.

예를 들어, 다음을 사용한다면:

echo a_song.mp3 | awk '{print "Mplayer: "$1}'

나는 내가 원하는 것을 얻습니다

Mplayer: a_song.mp3

첫 번째 명령이 작동하지 않는 이유는 무엇입니까?

백그라운드에서 이러한 프로세스를 여러 개 실행하려면 어떻게 해야 합니까?

답변1

많은grep표준 출력이 터미널인 경우 구현에서는 라인 버퍼링을 사용합니다. 표준 출력이 터미널인 경우 일반적으로 대화형 세션이므로 가능한 한 빨리 데이터를 얻으려고 합니다. 따라서 grep개행 문자가 표시되는 즉시 데이터가 표준 출력에 기록됩니다.

표준 출력이 터미널이 아닌 경우(일반적으로 비대화형 세션을 의미) grep블록 버퍼가 사용됩니다. 이는 grep개행 문자가 보일 때 표준 출력이 즉시 작성되지 않음을 의미합니다. grep표준 출력에 쓰기 전에 많은 양의 데이터(Linux의 경우 4096바이트)를 수집합니다.

일부 grep버전, 예:GNU grep또는BSD grep가지다--라인 버퍼링옵션. grep개행 문자가 표시되면 항상 표준 출력에 씁니다. 따라서 귀하의 예는 다음과 같습니다.

mplayer *.* 2>/dev/null | grep --line-buffered Playing | awk '{print "Mplayer: "$1}'

grep귀하의 버전이 그렇지 않은 경우 --line-buffer다음을 사용하여 모든 작업을 수행할 수 있습니다 awk.

mplayer *.* 2>/dev/null | awk '/Playing/{print "Mplayer: "$1}'

GNU coreutils에는 도구가 있습니다표준 버퍼명령 수정을 위한 버퍼입니다. 다음을 사용하여 언제든지 표준 출력에 라인 버퍼를 강제로 적용할 수 있습니다.

stdbuf -oL command

게다가버퍼링 해제출력 버퍼링을 비활성화하는 명령만 해당됩니다.

추가 읽기

관련 정보