Eine einfache Möglichkeit besteht darin, einen Pass von tr
hinzuzufügen um alle sich wiederholenden Feldtrennzeichen herauszudrücken:
$ ps | egrep 11383 | tr -s ' ' | cut -d ' ' -f 4
Bitte beachten Sie, dass die tr -s ' '
Option entfernt keine einzelnen führenden Leerzeichen. Wenn Ihre Spalte rechtsbündig ist (wie bei ps
pid)...
$ ps h -o pid,user -C ssh,sshd | tr -s " "
1543 root
19645 root
19731 root
Dann führt das Ausschneiden zu einer Leerzeile für einige dieser Felder, wenn es sich um die erste Spalte handelt:
$ <previous command> | cut -d ' ' -f1
19645
19731
Es sei denn, Sie stellen ihm offensichtlich ein Leerzeichen voran
$ <command> | sed -e "s/.*/ &/" | tr -s " "
Nun, für diesen speziellen Fall von PID-Nummern (nicht Namen) gibt es eine Funktion namens pgrep
:
$ pgrep ssh
Shell-Funktionen
Generell ist es aber tatsächlich immer noch möglich, Shell-Funktionen zu verwenden in knapper Form, denn die read
hat eine nette Sache Befehl:
$ <command> | while read a b; do echo $a; done
Der erste zu lesende Parameter, a
, wählt die erste Spalte aus, und wenn es mehr gibt, alles andere wird in b
eingefügt . Dadurch benötigen Sie nie mehr Variablen als die Anzahl Ihrer Spalten +1 .
Also,
while read a b c d; do echo $c; done
gibt dann die 3. Spalte aus. Wie in meinem Kommentar angegeben...
Ein über Pipe geleiteter Lesevorgang wird in einer Umgebung ausgeführt, die keine Variablen an das aufrufende Skript weitergibt.
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'`
Die Array-Lösung
Am Ende haben wir also die Antwort von @frayser, die darin besteht, die Shell-Variable IFS zu verwenden, die standardmäßig ein Leerzeichen ist, um die Zeichenfolge in ein Array aufzuteilen. Es funktioniert jedoch nur in Bash. Dash und Ash unterstützen es nicht. Ich hatte eine wirklich harte Zeit, eine Zeichenfolge in einer Busybox-Sache in Komponenten aufzuteilen. Es ist einfach genug, eine einzelne Komponente zu erhalten (z. B. mit awk) und dies dann für jeden benötigten Parameter zu wiederholen. Aber am Ende rufen Sie wiederholt awk in derselben Zeile auf oder verwenden wiederholt einen read-Block mit echo in derselben Zeile. Was weder effizient noch hübsch ist. Sie teilen also am Ende mit ${name%% *}
usw. Macht Lust auf ein paar Python-Kenntnisse, denn tatsächlich macht Shell-Scripting keinen Spaß mehr, wenn die Hälfte oder mehr der Funktionen, an die man gewöhnt ist, weg sind. Aber Sie können davon ausgehen, dass nicht einmal Python auf einem solchen System installiert wäre, und das war es auch nicht;-).
Ich denke, der einfachste Weg ist die Verwendung von awk . Beispiel:
$ echo "11383 pts/1 00:00:00 bash" | awk '{ print $4; }'
bash