문제
나는 이것을하고 싶다 :
- 명령을 실행하다
- 출력을 캡처
- 라인을 선택하세요
- 해당 줄의 열을 선택하십시오
예를 들어, $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
빈 문자열을 선택합니다.물론, 나는 사용할 수 있었다 cut
4번째 필드가 아닌 7번째 필드를 선택하려면 어떻게 해야 합니까? 특히 출력이 가변적이고 미리 알 수 없는 경우에 그렇습니다.
해결책
쉬운 방법 중 하나는 패스를 추가하는 것입니다 Tr
반복 된 필드 분리기를 압박하려면 :
$ ps | egrep 11383 | tr -s ' ' | cut -d ' ' -f 4
다른 팁
가장 간단한 방법은 사용하는 것이라고 생각합니다 어색한. 예시:
$ echo "11383 pts/1 00:00:00 bash" | awk '{ print $4; }'
bash
참고하시기 바랍니다 tr -s ' '
옵션은 단일 선행 공백을 제거하지 않습니다.열이 오른쪽 정렬된 경우( ps
pid)...
$ 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 " "
이제 (이름이 아닌) pid 번호의 특별한 경우에 다음과 같은 함수가 있습니다. pgrep
:
$ pgrep ssh
쉘 기능
그러나 일반적으로 실제로는 여전히 사용할 수 있습니다. 쉘 기능 간결하게 정리하면 좋은 점이 있기 때문입니다. read
명령:
$ <command> | while read a b; do echo $a; done
읽어야 할 첫 번째 매개변수는 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'`
어레이 솔루션
그래서 우리는 문자열을 배열로 분할하기 위해 기본적으로 공백을 사용하는 쉘 변수 IFS를 사용하는 @frayser의 답변으로 끝납니다.하지만 Bash에서만 작동합니다.Dash와 Ash는 이를 지원하지 않습니다.저는 Busybox에서 문자열을 구성 요소로 나누는 데 정말 어려움을 겪었습니다.단일 구성요소를 얻는 것은 충분히 쉽습니다(예:awk를 사용하여) 필요한 모든 매개변수에 대해 이를 반복합니다.그러나 결국 동일한 라인에서 반복적으로 awk를 호출하거나 동일한 라인에서 echo가 포함된 읽기 블록을 반복적으로 사용하게 됩니다.효율적이지 않거나 예쁘지 않습니다.그래서 당신은 다음을 사용하여 분할하게됩니다. ${name%% *}
등등.실제로 익숙한 기능 중 절반 이상이 사라지면 쉘 스크립팅은 더 이상 재미가 없기 때문에 일부 Python 기술을 갈망하게 됩니다.그러나 그러한 시스템에는 Python조차도 설치되지 않을 것이라고 가정할 수 있으며, 그렇지 않았습니다 ;-).
노력하다
ps |&
while read -p first second third fourth etc ; do
if [[ $first == '11383' ]]
then
echo got: $fourth
fi
done
Brianegge의 AWK 솔루션과 유사하게 여기에는 Perl이 동등합니다.
ps | egrep 11383 | perl -lane 'print $F[3]'
-a
AutoSplit 모드를 사용하여 채워집니다 @F
열 데이터와 함께 배열.
사용 -F,
데이터가 공간에 해석되지 않고 쉼표로 분류 된 경우.
Perl이 1이 아닌 0에서 계산하기 시작하기 때문에 필드 3이 인쇄됩니다.
올바른 선 (6 행 6의 예)를 얻는 것은 머리와 꼬리로 수행되며 올바른 단어 (단어 번호 4)를 awk로 캡처 할 수 있습니다.
command|head -n 6|tail -n 1|awk '{print $4}'
배열 변수 사용
set $(ps | egrep "^11383 "); echo $4
또는
A=( $(ps | egrep "^11383 ") ) ; echo ${A[3]}
이 모든 그레프와 작업을 수행하는 대신 출력 형식 변경의 PS 기능을 사용하는 것이 좋습니다.
ps -o cmd= -p 12345
PID가 지정된 프로세스의 CMMAND 라인을 얻지 못하고 다른 것은 없습니다.
이것은 posix- 정보이므로 휴대용으로 간주 될 수 있습니다.
당신의 명령
ps | egrep 11383 | cut -d" " -f 4
그리워 a tr -s
Unloind가 설명하는 것처럼 공간을 짜기 위해 그의 대답.
그러나 사용하고 싶을 수도 있습니다 awk
,이 모든 작업을 단일 명령으로 처리하므로 다음과 같습니다.
ps | awk '/11383/ {print $4}'
이것은 포함 된 선에서 4 번째 열을 인쇄합니다 11383
. 이것을 일치시키기를 원한다면 11383
줄의 시작 부분에 나타나면 말할 수 있습니다. ps | awk '/^11383/ {print $4}'
.
배쉬 set
모든 출력을 위치 매개 변수로 구문 분석합니다.
예를 들어, set $(free -h)
명령, echo $7
"Mem :"를 보여줄 것입니다.