GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Ausgabe des Befehls nach Spalten mit Bash aufteilen?

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

Linux
  1. Verwenden des Linux-Sleep-Befehls in Bash-Skripten

  2. Verwenden des Linux-Basisnamenbefehls in Bash-Skripten

  3. Bash-Exportbefehl

  4. Alle Ausgaben mit Bash unter Linux in eine Datei umleiten?

  5. Ausgabe des Zeitbefehls in Unix in eine Variable in Bash umleiten?

Bash:In Datei schreiben

Bash Heredoc

Bash-Quellbefehl

Bash-printf-Befehl

Zeigen Sie die Ping-Befehlsausgabe im Diagrammformat mit Gping an

Verwenden des Linux-Dirname-Befehls in Bash-Skripten