Как указать больше пробелов для разделителя, используя cut?

Можно ли указать разделитель полей для большего количества пробелов с помощью команды 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"?

спасибо.

Ответ 1

Фактически 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, которую используют некоторые люди.

Ответ 2

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

Ответ 3

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

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

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

Ответ 4

Один из способов сделать это:

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

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

Ответ 5

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

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

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

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

Ответ 6

Короче/более простое решение: используйте cuts (на стероидах я писал)

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

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

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

И даже короче (не используя вырезать) это:

pgrep jboss

Ответ 7

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

ps axu| grep jboss | grep -v grep | awk '{print $5}'

Ответ 8

Если вы хотите выбрать столбцы из вывода 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})"

Ответ 9

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

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

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

ps aux | perl -lane 'print @F[3 .. scalar @F]'

Ответ 10

Другой способ, если вы должны использовать команду cut

ps axu | grep [j]boss |awk '$1=$1'|cut -d' ' -f5

В Solaris замените awk на nawk или /usr/xpg4/bin/awk

Ответ 11

Мне все еще нравится, как Perl обрабатывает поля с пробелом.
Первое поле - $F [0].

$ ps axu | grep dbus | perl -lane 'print $F[4]'

Ответ 12

Мой подход заключается в том, чтобы сохранить 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 [email protected]$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 подходом может быть запрос SSH_PID непосредственно перед его уничтожением, поскольку файл может устареть и уничтожить неправильный процесс.