2017-02-28 16 views
0

ps 명령에 의해 반환 된 데이터를 구문 분석해야하는 스크립트 작업. Redhat/Centos에서는 열 구분 기호를 지정하기가 쉽지만 BSD version of PS과 같이 간단하지는 않습니다.OSX (BSD)에서 PS 열 구분 기호 설정

나는, 출력이 될 것이다는 어떤 문자로 공백을 대체 할 awk, sed 또는 tr을 사용하는 것이 가능하지만, 형식이 args 또는 어딘가에 중간에 comm을 가지고 말할 수 것 알고

$ ps -o pid,ppid,args,user | head 
    PID PPID ARGS                USER 
60140 494 /Applications/iTerm.app/Contents/MacOS/iTerm2 --server login -fp jdoe 
60144 60141 -bash               jdoe 
55574 494 /Applications/iTerm.app/Contents/MacOS/iTerm2 --server login -fp jdoe 
55576 55575 -bash               jdoe 
20710 494 /Applications/iTerm.app/Contents/MacOS/iTerm2 --server login -fp jdoe 
20712 20711 -bash               jdoe 
66703 494 /Applications/iTerm.app/Contents/MacOS/iTerm2 --server login -fp jdoe 
66707 66704 -bash               jdoe 
66881 494 /Applications/iTerm.app/Contents/MacOS/iTerm2 --server login -fp jdoe 

보시다시피, args 열의 데이터에는 공백이있을 수 있습니다.

정말 자극적인데, 결과물 끝에 args을 넣지 않아도 정상적으로 작동하는 것으로 보이는 솔루션이 실제로 발견되었지만 해결책을 기억하지 못하거나 다시 찾을 수 있습니다.

헤더가 열 데이터와 정렬되기 때문에 열 머리글 행을 사용하여 열의 너비를 결정할 수 있다고 생각 했었지만 그보다 간단한 해결책이 있습니다.

도움을 주시면 감사하겠습니다. 감사!

+1

왜 그냥'마지막 열로 args' 수없고,'Awk'와 데이터를 읽어? 그런 식으로 사용할 수 있습니까? – Inian

+0

유일한 확실한 구분 기호는 null 문자입니다. – chepner

+0

이 데이터로 실제로 무엇을하고 싶습니까? 너 최종 게임이 뭐니? 우리가 목표를 달성하는 방법을 알아낼 수 있는지 알아 봅시다. 잘못된 길을 알려주는 것만 보지 마십시오. – ghoti

답변

0
ps -o pid,ppid,args,user \ 
awk -v Rpl='_' ' 
    # line but the header 
    NR > 1 { 
     p = $1 
     P = $2 
     u = $NF 
     A = $0 
     sub("^[[:blank:]*" p "[[:blank:]*" P "[[:blank:]*", "", A) 
     sub("[[:blank:]*" u "[[:blank:]*$", "", A) 
     gsub(" ", Rpl, A) 

     # recreate the line 
     $0 = sprintf("%d\t%d\t%s\t%s\n", p, P, A, u) 
     } 

    # print the line 
    7 
    ' 

참고 :

  • 내가 어디서, 어떻게 정보를 활용하려면 보여주기 위해 필요 이상으로 추가 코드를 사용, P, P와 U 직접 $ 1이 될 수 있습니다 ...
  • 내가 다시 라인, 직접 인쇄 할 수 있습니다. 이 경우 라인이나 내용을 다루고 더 명확하게 표현하고자합니다.
  • 7은 현재 줄을 인쇄하는 기본 동작으로 0이 아닌 (개인 농담, 1은 충분하지만 혼동하지 않음)
  • Rpl 콘텐츠 (배치 상호 작용을 허용하기 위해 awk 외부에 할당 됨)는 공백은 무엇이든 될 수 있습니다 (비어 있음).
  • 새 분리 기호로 \t을 사용합니다. 다른 것이 될 수 있습니다.
  • 는 ps의 다른 필드가 사용되면 적응하지만 그 중 몇 개가 내부에 잠재적 인 공간이 있으면 작동하지 않습니다.
+0

'args' 열의 값 중 일부는 공백을 포함하며,이 공백이 함께 병합됩니다. 그 문제를 해결할 방법을 알고 있습니까? 'args' 칼럼에서 공백을'||'와 같은 것으로 바꾸면, 출력 할 때'||'를 공백으로 대체하십시오. 하지만 그 외에는, 내가 가진 것보다 분명히 좋습니다. – Justin

+0

편집 : 위의 내용을 게시하기 전에 논리를 완전히 조사하지 않았습니다. 그러나 기둥이 움직이면이 일은 제대로되지 않을까요? 나는 그 글을 올렸어야했지만 칼럼을 옮길 수 있어야한다. – Justin

+0

은 간격 필드를 정의하는 유일한 제약 조건이며 1이있는 경우 여기에서 다른 필드의 위치를 ​​추측 할 수 있습니다. 가장 쉬운 방법은 필드를 간격을두고 (ARGS는 여기에 넣으십시오) 마지막 장소에 주문하여 다른 곳에서 잡기 쉽고 필터링하기가 쉽습니다. – NeronLeVelu

-1
최신 FreeBSD11에서

PS 유틸리티는이 옵션은 이전 BSD에서 유래 PS 유틸리티를 사용할 수 없습니다하지만 XML, 텍스트, JSON 등의 ps의 출력을 포맷 할 수 있습니다 --libxo 옵션을 (가지고 즉, 오픈 BSD 6 또는 freebsd 미만 11). --libxo를 사용할 수있는 경우

하나의 해결 방법은 ps --libxo json을 사용하고 당신이 필요로하는 값을 검색 할 jq를 사용하거나 sed 같은 다른 도구를 사용할 수 있습니다.

$ ps --libxo json -o pid,args |tr '}' '\n' |sed 's/["{:]//g;s/arguments//g;s/pid//g;s/^,//g' 

804,-csh (csh) 
813,dbus-launch --sh-syntax --exit-with-session 
816,xinit /usr/local/etc/xdg/xfce4/xinitrc 
817,X 0 (Xorg) 
819,sh /usr/local/etc/xdg/xfce4/xinitrc 
825,xfce4-session 
..................................................... 

당신은 내가 (쉼표 구분 기호에 따라 cut 포맷 STRAM 및 추출물 필드를 촉진 할 수

이 테스트를 참조하십시오.출력 위의 파이프가 |cut -d, -f2 일 경우에만 args를 줄 것입니다.

Offcourse jq를 사용하는 방법을 알고 있다면이 파이프와 seds가 모두 필요하지 않으므로 json 스트림에서 직접 필드를 추출 할 수 있습니다.

또한 man xo_parse_args에서 ps의 --libxo 옵션에 대한 추가 옵션을 볼 수 있습니다.

+0

@Justin 이것이 효과가 있었습니까? –

+0

아니요, OSX에 im이 있습니다. 그리고 적어도 --libxo 옵션은 없습니다. 적어도 제가 가지고있는 버전에는 없습니다. https://gist.github.com/jhyland87/6ff0266abc9a9b57690ab28dfc18c180 – Justin

+0

@Justin - FYI, OSX의'ps' 명령은 [FreeBSD 6.0의'ps' 명령을 기반으로합니다.] (https://www.freebsd.org/cgi/ man.cgi? query = ps & manpath = FreeBSD + 6.0-RELEASE) (2005 년 출시)에는'--libxo' 옵션이 포함되어 있지 않습니다. 이 옵션은 실제로 FreeBSD 11에 추가되었습니다 (https://www.freebsd.org/cgi/man.cgi?query=ps&manpath=FreeBSD+11.0-RELEASE).이 옵션은 2016 년에 발표되었습니다. – ghoti

0

글쎄, 당신의 bsd ps은 나의 이전 대답에 조언 된대로 --libxo을 지원하지 않기 때문에, 끝까지 간격을 둔 args를 넣어서 고전적인 bash 방식을 사용할 수 있습니다.

그런 다음 루프를 사용하여 어레이에서 전체 ps 출력을 읽을 수 있습니다. 그런 다음 해당 배열 항목의 인쇄를 조정하여 원하는 순서대로 작업을 인쇄 할 수 있습니다.

"구문 분석"의 경우 끝 부분에 간격을 유지해야합니다. 인쇄의 경우 배열을 다른 순서로 인쇄하면됩니다.

이 테스트를 참조하고, 배열 요소 No7,11,15에 공간을 마음 :

$ while read -r pid ppid user args;do \ 
psdata+=("$pid" "$ppid" "$user" "$args"); \ 
done< <(ps -o pid,ppid,user,args) 

$ declare -p psdata #let's ask bash to print the array for us 
declare -a psdata=([0]="PID" [1]="PPID" [2]="USER" [3]="COMMAND" [4]="769" \ 
[5]="1" [6]="root" [7]="/usr/libexec/getty Pc ttyv0" [8]="770" [9]="1" \ 
[10]="root" [11]="/usr/libexec/getty Pc ttyv1" [12]="771" [13]="1" [14]="root" \ 
[15]="/usr/libexec/getty Pc ttyv2" [16]="772" [17]="1" [18]="root" \ 
# more items here