Un moyen simple consiste à ajouter une passe de tr
pour éliminer tous les séparateurs de champs répétés :
$ ps | egrep 11383 | tr -s ' ' | cut -d ' ' -f 4
Veuillez noter que le tr -s ' '
L'option ne supprimera aucun espace de début unique. Si votre colonne est alignée à droite (comme avec ps
pid)...
$ ps h -o pid,user -C ssh,sshd | tr -s " "
1543 root
19645 root
19731 root
Ensuite, la coupure entraînera une ligne vide pour certains de ces champs s'il s'agit de la première colonne :
$ <previous command> | cut -d ' ' -f1
19645
19731
Sauf si vous le faites précéder d'un espace, évidemment
$ <command> | sed -e "s/.*/ &/" | tr -s " "
Maintenant, pour ce cas particulier de numéros pid (pas de noms), il existe une fonction appelée pgrep
:
$ pgrep ssh
Fonctions du shell
Cependant, en général, il est toujours possible d'utiliser les fonctions shell de manière concise, car il y a une chose intéressante à propos du read
commande :
$ <command> | while read a b; do echo $a; done
Le premier paramètre à lire, a
, sélectionne la première colonne, et s'il y en a plus, tout le reste sera mis en b
. Par conséquent, vous n'avez jamais besoin de plus de variables que le numéro de votre colonne +1 .
Alors,
while read a b c d; do echo $c; done
affichera alors la 3e colonne. Comme indiqué dans mon commentaire...
Une lecture canalisée sera exécutée dans un environnement qui ne transmet pas de variables au script appelant.
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'`
La solution de tableau
Nous nous retrouvons donc avec la réponse de @frayser qui consiste à utiliser la variable shell IFS qui par défaut est un espace, pour diviser la chaîne en un tableau. Cela ne fonctionne que dans Bash cependant. Dash et Ash ne le supportent pas. J'ai eu beaucoup de mal à diviser une chaîne en composants dans une chose Busybox. Il est assez facile d'obtenir un seul composant (par exemple en utilisant awk), puis de le répéter pour chaque paramètre dont vous avez besoin. Mais ensuite, vous finissez par appeler à plusieurs reprises awk sur la même ligne, ou à utiliser à plusieurs reprises un bloc de lecture avec echo sur la même ligne. Ce qui n'est ni efficace ni joli. Donc, vous finissez par diviser en utilisant ${name%% *}
etc. Vous donne envie d'acquérir certaines compétences Python, car en fait, les scripts shell ne sont plus très amusants si la moitié ou plus des fonctionnalités auxquelles vous êtes habitué ont disparu. Mais vous pouvez supposer que même python ne serait pas installé sur un tel système, et ce n'était pas le cas;-).
Je pense que le moyen le plus simple est d'utiliser awk . Exemple :
$ echo "11383 pts/1 00:00:00 bash" | awk '{ print $4; }'
bash