Est-il possible de spécifier un délimiteur de champ pour plus d'espaces avec la commande cut? (comme "" +)? Par exemple: dans la chaîne suivante, j'aime bien atteindre la valeur '3744', quel délimiteur de champ devrais-je dire?
$ps axu | grep jboss
jboss 2574 0.0 0.0 3744 1092 ? S Aug17 0:00 /bin/sh /usr/Java/jboss/bin/run.sh -c example.com -b 0.0.0.0
cut -d' '
n'est pas ce que je veux, car ce n'est que pour un seul espace. awk
n'est pas ce que je recherche non plus, mais comment faire avec 'couper'?
merci.
En fait, awk
est exactement l'outil sur lequel vous devriez vous pencher:
ps axu | grep '[j]boss' | awk '{print $5}'
ou vous pouvez abandonner complètement la grep
puisque awk
connaît les expressions régulières:
ps axu | awk '/[j]boss/ {print $5}'
Mais si, pour une raison étrange, vous ne pouvez pas utiliser awk
, vous pouvez faire d'autres choses plus simples, comme réduire tout d'abord les espaces blancs à un seul espace:
ps axu | grep '[j]boss' | sed 's/\s\s*/ /g' | cut -d' ' -f5
Cette astuce grep
est d'ailleurs un moyen astucieux de n'obtenir que les processus jboss
et pas le processus grep jboss
(idem pour la variante awk
également).
Le processus grep
aura un littéral grep [j]boss
dans sa commande de processus, de sorte qu'il ne sera pas attiré par le grep
lui-même, qui recherche la classe de caractères [j]
suivie de boss
.
C'est un moyen astucieux d'éviter le paradigme | grep xyz | grep -v grep
que certaines personnes utilisent.
La version awk
est probablement la meilleure solution, mais vous pouvez également utiliser cut
si vous comprimez d'abord les répétitions avec tr
:
ps axu | grep jbos[s] | tr -s ' ' | cut -d' ' -f5
# ^^^^^^^^^^^^ ^^^^^^^^^ ^^^^^^^^^^^^^
# | | |
# | | get 5th field
# | |
# | squeeze spaces
# |
# avoid grep itself to appear in the list
J'aime utiliser la commande tr -s pour cela
ps aux | tr -s [:blank:] | cut -d' ' -f3
Cela réduit tous les espaces blancs à 1 espace. De cette manière, l'utilisation d'un espace en tant que délimiteur est respectée comme prévu.
Je vais nommer tr -s [:blank:]
comme la meilleure réponse.
Pourquoi voulons-nous utiliser la coupe? Il a la commande magique qui dit "nous voulons le troisième champ et tous les champs après, en omettant les deux premiers champs"
cat log | tr -s [:blank:] |cut -d' ' -f 3-
Je ne crois pas qu'il y ait une commande équivalente pour awk ou Perl split où nous ne savons pas combien de champs il y aura, c'est-à-dire que le troisième champ est sorti du champ X.
cuts
(couper sur les stéroïdes que j'ai écrits)ps axu | grep '[j]boss' | cuts 4
Notez que les index de champs cuts
sont basés sur zéro. Le cinquième champ est donc 4
Et même plus court (pas du tout coupé) est:
pgrep jboss
Une façon de contourner cela est d'aller:
$ps axu | grep jboss | sed 's/\s\+/ /g' | cut -d' ' -f3
pour remplacer plusieurs espaces consécutifs par un seul.
Personnellement, j'ai tendance à utiliser awk pour des emplois comme celui-ci. Par exemple:
ps axu| grep jboss | grep -v grep | awk '{print $5}'
Si vous voulez choisir des colonnes dans une sortie ps, avez-vous une raison de ne pas utiliser -o?
par exemple.
ps ax -o pid,vsz
ps ax -o pid,cmd
Largeur de colonne minimale allouée, pas de remplissage, uniquement un séparateur de champ à espace unique.
ps ax --no-headers -o pid:1,vsz:1,cmd
3443 24600 -bash
8419 0 [xfsalloc]
8420 0 [xfs_mru_cache]
8602 489316 /usr/sbin/Apache2 -k start
12821 497240 /usr/sbin/Apache2 -k start
12824 497132 /usr/sbin/Apache2 -k start
Pid et vsz étant donné une largeur de 10 caractères, un séparateur de champs d'espace.
ps ax --no-headers -o pid:10,vsz:10,cmd
3443 24600 -bash
8419 0 [xfsalloc]
8420 0 [xfs_mru_cache]
8602 489316 /usr/sbin/Apache2 -k start
12821 497240 /usr/sbin/Apache2 -k start
12824 497132 /usr/sbin/Apache2 -k start
Utilisé dans un script: -
oldpid=12824
echo "PID: ${oldpid}"
echo "Command: $(ps -ho cmd ${oldpid})"
Comme alternative, il y a toujours Perl:
ps aux | Perl -lane 'print $F[3]'
Ou, si vous souhaitez obtenir tous les champs à partir du champ n ° 3 (comme indiqué dans l'une des réponses ci-dessus):
ps aux | Perl -lane 'print @F[3 .. scalar @F]'
J'aime toujours la façon dont Perl gère les champs avec des espaces.
Le premier champ est $ F [0].
$ ps axu | grep dbus | Perl -lane 'print $F[4]'
Mon approche consiste à stocker le PID dans un fichier dans/tmp et à trouver le bon processus à l'aide de l'option -S
pour ssh
. Cela pourrait être un abus, mais cela fonctionne pour moi.
#!/bin/bash
TARGET_REDIS=${1:-redis.someserver.com}
PROXY="proxy.somewhere.com"
LOCAL_PORT=${2:-6379}
if [ "$1" == "stop" ] ; then
kill `cat /tmp/sshTunel${LOCAL_PORT}-pid`
exit
fi
set -x
ssh -f -i ~/.ssh/aws.pem centos@$PROXY -L $LOCAL_PORT:$TARGET_REDIS:6379 -N -S /tmp/sshTunel$LOCAL_PORT ## AWS DocService dev, DNS alias
# SSH_PID=$! ## Only works with &
SSH_PID=`ps aux | grep sshTunel${LOCAL_PORT} | grep -v grep | awk '{print $2}'`
echo $SSH_PID > /tmp/sshTunel${LOCAL_PORT}-pid
Une meilleure approche consisterait peut-être à rechercher le SSH_PID
juste avant de le tuer, car le fichier peut être périmé et tuer un processus erroné.
Une autre façon si vous devez utiliser la commande cut
ps axu | grep [j]boss |awk '$1=$1'|cut -d' ' -f5
Sous Solaris, remplacez awk par nawk
ou /usr/xpg4/bin/awk