programing

Bash를 사용하여 명령 출력을 열로 분할하시겠습니까?

powerit 2023. 5. 23. 22:33
반응형

Bash를 사용하여 명령 출력을 열로 분할하시겠습니까?

이 작업을 수행합니다.

  1. 명령을 실행합니다.
  2. 산출물을 포착합니다.
  3. 대사를 고르다
  4. 해당 줄의 열을 선택합니다.

예를 들어, 명령 이름을 다음에서 가져오려고 합니다.$PID(이것은 단지 예시일 뿐입니다. 저는 이것이 프로세스 ID에서 명령 이름을 가져오는 가장 쉬운 방법이라고 제안하는 것이 아닙니다. 제 진짜 문제는 출력 형식을 제어할 수 없는 다른 명령에 있습니다.)

가 가내뛰면을 하면,ps이해합니다.


  PID TTY          TIME CMD
11383 pts/1    00:00:00 bash
11771 pts/1    00:00:00 ps

이제 나는 한다.ps | egrep 11383그리고 구함

11383 pts/1    00:00:00 bash

단계: 다음단:ps | egrep 11383 | cut -d" " -f 4출력:

<absolutely nothing/>

는 문는입니다.cut하고 "" " " " " " 로 표시됩니다.ps 두 번째 과 세 번째 열 합니다.cut빈 문자열을 선택합니다.물론, 저는 사용할 수 있습니다.cut4번째 필드가 아닌 7번째 필드를 선택하는 것입니다. 특히 출력이 가변적이고 사전에 알 수 없는 경우 어떻게 알 수 있습니까?

한 가지 쉬운 방법은 다음의 패스를 추가하는 것입니다.tr반복되는 필드 구분 기호를 압착합니다.

$ ps | egrep 11383 | tr -s ' ' | cut -d ' ' -f 4

저는 가장 간단한 방법은 awk를 사용하는 것이라고 생각합니다.예:

$ echo "11383 pts/1    00:00:00 bash" | awk '{ print $4; }'
bash

참고로 다음은tr -s ' '옵션을 사용하면 선행 공백이 하나도 제거되지 않습니다.정렬된 (" " " " " " "와 같이 정렬된 경우:pspid)...

$ ps h -o pid,user -C ssh,sshd | tr -s " "
 1543 root
19645 root
19731 root

그런 다음 일부 필드가 첫 번째 열인 경우 필드를 잘라내면 빈 줄이 됩니다.

$ <previous command> | cut -d ' ' -f1

19645
19731

당신이 공백으로 앞서지 않는 한, 분명히.

$ <command> | sed -e "s/.*/ &/" | tr -s " "

이 (이름이 ) 숫자의 에, 이제, (으)ㄹ 수 있다, 다이숫의경, 음같함있라고 하는 .pgrep:

$ pgrep ssh


함수

그러나, 일반적으로 셸 함수를 간결하게 사용하는 것은 여전히 가능합니다. 왜냐하면 그것에는 깔끔한 것이 있기 때문입니다.read명령:

$ <command> | while read a b; do echo $a; done

, 첫번로읽매을변수는개째▁to▁the,,a첫 번째 열을 선택하고, 더 많은 열이 있을 경우 다른 모든 열이 삽입됩니다.b따라서 열 수 +1보다 많은 변수가 필요하지 않습니다.

그렇게,

while read a b c d; do echo $c; done

그러면 세 번째 열이 출력됩니다.내 의견에 나타난 바와 같이...

호출 스크립트에 변수를 전달하지 않는 환경에서 파이프 판독이 실행됩니다.

out=$(ps whatever | { read a b c d; echo $c; })

arr=($(ps whatever | { read a b c d; echo $c $b; }))
echo ${arr[1]}     # will output 'b'`


솔루션

그래서 우리는 @frayser의 답으로 끝납니다. 공간을 기본으로 하는 셸 변수 IFS를 사용하여 문자열을 배열로 분할하는 것입니다.하지만 그것은 Bash에서만 작동합니다.Dash 및 Ash는 지원하지 않습니다.저는 Busybox 같은 것에서 문자열을 구성 요소로 나누는 것이 정말 어려웠습니다.단일 구성 요소(예: awk 사용)를 얻은 다음 필요한 모든 매개 변수에 대해 이를 반복할 수 있습니다.그러나 같은 회선에서 Awk를 반복적으로 호출하거나 같은 회선에서 에코가 있는 읽기 블록을 반복적으로 사용하게 됩니다.효율적이지도 않고 예쁘지도 않은 것.그래서 당신은 결국 다음을 사용하여 분열하게 됩니다.${name%% *}등등.익숙한 기능의 절반 이상이 사라지면 셸 스크립팅은 더 이상 재미가 없기 때문에 일부 Python 기술을 동경하게 됩니다.하지만 파이썬조차 그런 시스템에 설치되지 않았을 것이고 ;-)이 아니었다고 가정할 수 있습니다.

해라

ps |&
while read -p first second third fourth etc ; do
   if [[ $first == '11383' ]]
   then
       echo got: $fourth
   fi       
done

당신의 명령

ps | egrep 11383 | cut -d" " -f 4

tr -s의 대답에서 설명한 것처럼 공간을 짜내는 것.

하지만, 당신은 아마도 사용하기를 원할 것입니다.awk하기 때문입니다.

ps | awk '/11383/ {print $4}'

은 다을번포행는열인째 4이다니쇄됩이 포함된 합니다.11383과 일치하기를 일시키면려.11383만약 그것이 줄의 시작에 나타난다면, 당신은 말할 수 있습니다.ps | awk '/^11383/ {print $4}'.

배열 변수 사용

set $(ps | egrep "^11383 "); echo $4

또는

A=( $(ps | egrep "^11383 ") ) ; echo ${A[3]}

brianege의 awk 솔루션과 유사한 Perl 등가물은 다음과 같습니다.

ps | egrep 11383 | perl -lane 'print $F[3]'

-a를 활성화합니다. 자동 분할 모드는 자동분활합다니성화를 . 자동 분할 모드는 다음을 채웁니다.@F열 데이터가 있는 배열입니다.
사용하다-F,데이터가 공백으로 구분되지 않고 쉼표로 구분된 경우

Perl이 1이 아닌 0부터 카운트를 시작하므로 필드 3이 인쇄됩니다.

정확한 선(예: 6번 선)을 얻는 것은 머리와 꼬리로 이루어지며, 정확한 단어(4번 단어)는 다음과 같이 Awk로 캡처할 수 있습니다.

command|head -n 6|tail -n 1|awk '{print $4}'

이 모든 greps 같은 것들을 하는 대신에 출력 형식을 변경하는 ps 기능을 사용하는 것이 좋습니다.

ps -o cmd= -p 12345

pid가 지정되고 다른 것이 지정되지 않은 공정의 명령줄을 얻을 수 있습니다.

이는 POSIX를 준수하므로 휴대용으로 간주할 수 있습니다.

바시의set모든 출력을 위치 매개 변수로 구문 분석합니다.

를 들어, 예들어를 사용하면 다과같이 .set $(free -h) 명령,echo $7는 " "Mem:" "Mem:"을 표시합니다.

언급URL : https://stackoverflow.com/questions/1629908/split-output-of-command-by-columns-using-bash

반응형