Как указать больше пробелов для разделителя, используя cut? - PullRequest
166 голосов
/ 22 августа 2011

Есть ли способ указать разделитель полей для большего количества пробелов командой cut? (как "" +)? Например: в следующей строке мне нравится достигать значения «3744», какой разделитель я должен сказать?

$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' ' не то, что я хочу, потому что это только для одного пробела. awk это не то, что я ищу, а как делать с 'cut'?

спасибо.

Ответы [ 12 ]

274 голосов
/ 22 августа 2011

На самом деле awk - это точно инструмент, на который вы должны обратить внимание:

ps axu | grep '[j]boss' | awk '{print $5}'

или вы можете вообще отказаться от grep, так как awk знает о регулярных выражениях:

ps axu | awk '/[j]boss/ {print $5}'

Но если по какой-то причудливой причине вы действительно не можете использовать awk, есть и другие более простые вещи, которые вы можете сделать, например свертывание всех пробелов в один пробелво-первых:

ps axu | grep '[j]boss' | sed 's/\s\s*/ /g' | cut -d' ' -f5

Этот трюк grep, кстати, является изящным способом получить только процессы jboss, а не grep jboss (то же самое для awkтакже вариант).

Процесс grep будет иметь литерал grep [j]boss в своей команде процесса, поэтому он не будет перехвачен самим grep, который ищет класс символов, за которым следует [j]boss.

Это отличный способ избежать парадигмы | grep xyz | grep -v grep, которую используют некоторые люди.

92 голосов
/ 31 января 2014

awk версия, вероятно, лучший путь, но вы также можете использовать cut, если вы сначала сжимаете повторы с tr:

ps axu | grep jbos[s] | tr -s ' ' | cut -d' ' -f5
#        ^^^^^^^^^^^^   ^^^^^^^^^   ^^^^^^^^^^^^^
#              |            |             |
#              |            |       get 5th field
#              |            |
#              |        squeeze spaces
#              |
#        avoid grep itself to appear in the list
24 голосов
/ 16 апреля 2015

Мне нравится использовать команду tr -s для этого

 ps aux | tr -s [:blank:] | cut -d' ' -f3

Это сжимает все пробелы до 1 пробела. Таким образом, указание вырезать использование пробела в качестве разделителя считается ожидаемым.

9 голосов
/ 05 мая 2015

Я собираюсь назначить tr -s [:blank:] как лучший ответ.

Почему мы хотим использовать вырезать? У него есть магическая команда, которая говорит: «мы хотим, чтобы третье поле и каждое поле после него пропускали первые два поля»

cat log | tr -s [:blank:] |cut -d' ' -f 3- 

Я не верю, что существует эквивалентная команда для разделения на awk или perl, где мы не знаем, сколько будет полей, т.е. выведите третье поле через поле X.

7 голосов
/ 03 июля 2014

Сокращенное / простое решение: используйте cuts (вырезать на стероидах, которые я написал)

ps axu | grep '[j]boss' | cuts 4

Обратите внимание, что cuts индексы полей начинаются с нуля, поэтому 5поле указывается как 4

http://arielf.github.io/cuts/

И еще короче (без использования вырезания):

pgrep jboss
7 голосов
/ 22 августа 2011

Один из способов обойти это:

$ps axu | grep jboss | sed 's/\s\+/ /g' | cut -d' ' -f3

для замены нескольких последовательных пробелов на один.

4 голосов
/ 22 августа 2011

Лично я склонен использовать awk для таких работ.Например:

ps axu| grep jboss | grep -v grep | awk '{print $5}'
2 голосов
/ 11 сентября 2018

Если вы хотите выбрать столбцы из вывода ps, есть ли причина не использовать -o?

например,

ps ax -o pid,vsz
ps ax -o pid,cmd

Минимальная ширина столбца, без заполнения, только одно полеразделитель.

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 и vsz с шириной 10 символов, 1 разделитель пробелов.

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

Используется в сценарии: -

oldpid=12824
echo "PID: ${oldpid}"
echo "Command: $(ps -ho cmd ${oldpid})"
1 голос
/ 26 февраля 2016

В качестве альтернативы всегда есть perl:

ps aux | perl -lane 'print $F[3]'

Или, если вы хотите, чтобы все поля начинались с поля № 3 (как указано в одном из ответов выше):

ps aux | perl -lane 'print @F[3 .. scalar @F]'
0 голосов
/ 07 февраля 2018

Мой подход заключается в том, чтобы сохранить PID в файле в / tmp и найти правильный процесс, используя параметр -S для ssh. Это может быть неправильно, но у меня работает.

#!/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

Лучшим подходом может быть запрос SSH_PID прямо перед его уничтожением, так как файл может устареть и уничтожить неправильный процесс.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...