Bash를 사용하여 열별로 명령 출력을 분할 하시겠습니까?
나는 이것을하고 싶다 :
- 명령을 실행하다
- 출력 캡처
- 라인을 선택
- 해당 줄의 열을 선택
예를 들어, a에서 명령 이름을 얻고 싶다고 가정 해 봅시다 $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
가장 간단한 방법은 awk 를 사용하는 것 입니다. 예:
$ 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'`
어레이 솔루션
그래서 우리는 @frayser의 대답으로 끝납니다. 이것은 기본값이 공백 인 쉘 변수 IFS를 사용하여 문자열을 배열로 분할하는 것입니다. 그래도 Bash에서만 작동합니다. Dash와 Ash는이를 지원하지 않습니다. Busybox 사물에서 문자열을 구성 요소로 나누는 데 정말 어려움을 겪었습니다. 단일 구성 요소 (예 : awk 사용)를 얻은 다음 필요한 모든 매개 변수에 대해 반복하는 것이 쉽습니다. 그러나 같은 줄에서 반복적으로 awk를 호출하거나 같은 줄에서 echo가있는 읽기 블록을 반복적으로 사용합니다. 효율적이거나 예쁘지 않습니다. 그래서 당신은${name%% *}
등등. 실제로 익숙한 기능의 절반 이상이 사라지면 쉘 스크립팅이 더 이상 재미 없기 때문에 일부 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
@F
열 데이터로 배열 을 채우는 자동 분할 모드를 활성화 합니다. 데이터가 공백으로 구분되지 않고 쉼표로 구분 된 경우
사용 -F,
합니다.
Perl이 1이 아닌 0부터 계산을 시작하므로 필드 3이 인쇄됩니다.
올바른 줄 (6 번 줄의 예)을 얻는 것은 head와 tail로 이루어지며 올바른 단어 (단어 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]}
Instead of doing all these greps and stuff, I'd advise you to use ps capabilities of changing output format.
ps -o cmd= -p 12345
You get the cmmand line of a process with the pid specified and nothing else.
This is POSIX-conformant and may be thus considered portable.
Your command
ps | egrep 11383 | cut -d" " -f 4
misses a tr -s
to squeeze spaces, as unwind explains in his answer.
However, you maybe want to use awk
, since it handles all of these actions in a single command:
ps | awk '/11383/ {print $4}'
This prints the 4th column in those lines containing 11383
. If you want this to match 11383
if it appears in the beginning of the line, then you can say ps | awk '/^11383/ {print $4}'
.
Bash's set
will parse all output into position parameters.
For instance, with set $(free -h)
command, echo $7
will show "Mem:"
참고URL : https://stackoverflow.com/questions/1629908/split-output-of-command-by-columns-using-bash
'development' 카테고리의 다른 글
패키지 이름에서 애플리케이션 이름 가져 오기 (0) | 2020.10.13 |
---|---|
여러 줄을 쉼표로 구분하여 한 줄로 바꾸기 (Perl / Sed / AWK) (0) | 2020.10.13 |
Spring Boot의 spring.jpa.open-in-view = true 속성은 무엇입니까? (0) | 2020.10.13 |
RecyclerView 항목에 잔물결 효과 추가 (0) | 2020.10.13 |
Haml을 Rails와 함께 사용하려면 어떻게해야합니까? (0) | 2020.10.13 |