grep을 파이프하고 헤더를 유지하는 방법은 무엇입니까?

grep을 파이프하고 헤더를 유지하는 방법은 무엇입니까?

아래 예에서는 올바른 항목을 선택했지만 제목은 없으며 그 반대의 경우도 마찬가지입니다. 어떻게 둘 다 가질 수 있나요?

$ ps aux | grep 'gpart'
erwann    200603  0.0  0.0   2608    72 pts/3    S    12:57   0:00 /bin/sh /usr/sbin/gparted
root      200608  0.0  0.0   2608  1056 pts/3    S    12:57   0:00 /bin/sh /usr/sbin/gparted
root      200693  0.0  0.0   2608    68 pts/3    S    12:57   0:00 /bin/sh /usr/lib/udisks2/udisks2-inhibit /usr/sbin/gpartedbin
root      200700  1.9  0.2 264960 18620 pts/3    SLl  12:57   8:31 /usr/sbin/gpartedbin
root      202327 99.8  0.0   2520    64 pts/3    R    13:36 400:07 gpart -s 512 /dev/sdc
erwann    214723  0.0  0.0   9032   716 pts/4    S+   20:17   0:00 grep --color=auto gpart
$ ps aux | tee >(head -n1) >(grep 'gpart') > /dev/null
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND

답변1

고정 문자열을 검색하려면 gpartmultimatch 변형을 사용하여 grep첫 번째 줄 자체는 물론 일치하는 줄을 선택할 수 있습니다.

ps aux | grep -E '^USER|[g]part'

awk또는 첫 번째 줄과 패턴과 일치하는 모든 줄을 출력하는 솔루션을 사용하세요.

ps aux | awk 'NR==1 || /[g]part/'

두 경우 모두 의 첫 번째 문자는 gpart대괄호로 묶여 있습니다. 이는 자체적 grep으로 차단되거나 awk일치하기 때문입니다. (정규식에서 단일 문자를 포함하는 대괄호는 실제로는 작동하지 않으며 단순히 단일 문자 자체를 나타냅니다.)

예( ps질문에 표시된 출력을 기반으로 함)

ps aux | grep -E '^USER|[g]part'
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
erwann    200603  0.0  0.0   2608    72 pts/3    S    12:57   0:00 /bin/sh /usr/sbin/gparted
root      200608  0.0  0.0   2608  1056 pts/3    S    12:57   0:00 /bin/sh /usr/sbin/gparted
root      200693  0.0  0.0   2608    68 pts/3    S    12:57   0:00 /bin/sh /usr/lib/udisks2/udisks2-inhibit /usr/sbin/gpartedbin
root      200700  1.9  0.2 264960 18620 pts/3    SLl  12:57   8:31 /usr/sbin/gpartedbin
root      202327 99.8  0.0   2520    64 pts/3    R    13:36 400:07 gpart -s 512 /dev/sdc

답변2

실행 중인 실제 명령과 정확히 일치하는 경우(예: Linux에서는 /proc/PID/comm아님 /proc/PID/cmdline) 괜찮다 면 ps해당 -C옵션을 사용해 보세요. 예를 들어:

ps u -C gpart

에서 man ps:

-C cmdlist

명령 이름으로 선택합니다. 그러면 cmdlist에 지정된 실행 파일 이름을 가진 프로세스가 선택됩니다. 참고: 명령 이름은 명령줄과 다릅니다. 이전 버전의 procps와 커널에서는 이 명령 이름을 15자로 잘렸습니다. 이 제한은 두 가지 모두에 대해 더 이상 존재하지 않습니다. 15자만 일치시키는 데 의존하는 경우 더 이상 일치 항목을 얻지 못할 수 있습니다.

이렇게 하면 프로그램의 제목과 세부 정보가 표시되지만 프로그램은 표시 gpart되지 않습니다 gparted. 다음과 유사합니다(정확하지만 합성 출력 섹션은 실제로 gpart내 시스템에서 실행하고 있지 않기 때문에 질문에서 복사하여 붙여넣었습니다).

$ ps u -C gpart
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root      202327 99.8  0.0   2520    64 pts/3    R    13:36 400:07 gpart -s 512 /dev/sdc

그런데 cmdlist단일 명령 이름이거나 쉼표로 구분된 명령 이름 목록일 수 있습니다. 예를 들어 ps u -C gpart,gparted.


그런데 ps다른 옵션과 결합할 수도 있습니다. 예를 들어, 원하는 것이 프로세스의 PID뿐이라면 다음과 같습니다 gpart.

ps ho pid -C gpart

h헤더를 억제하고 o pidPID만 출력합니다.

심지어:

GPART_PID=$(ps ho pid -C gpart)

답변3

이 두 줄을 참조하는 경우 다음 중 하나를 수행하세요.

ps aux | egrep "^USER.*COMMAND|gpart"

px aux | grep -E "^USER.*COMMAND|gpart"

ps aux | awk '/^USER.*COMMAND/ || /gpart/'

명령 자체가 포함된 행을 일치시키지 않으려면 다음을 수행하십시오.

ps aux | egrep "^USER.*COMMAND|[g]part"

px aux | grep -E "^USER.*COMMAND|[g]part"

ps aux | awk '/^USER.*COMMAND/ || /[g]part/'

각 계열의 처음 두 명령은 grep"title"이 있는 행과 문자열이 있는 다른 행을 반환하는 데 사용되며 gpart, 마지막 명령은 awk동일한 작업을 수행하는 데 사용됩니다.

tee다른 명령도 이 명령을 수행하고 덜 복잡하므로 이 명령을 사용할 이유가 없습니다 .

관련 정보