Используйте awk / sed для удалить все, кроме соответствия шаблону в определенном столбце

При отправке сигнала на PID 0 (ноль) сигнал доставляется всем процессам, которые являются членами той же группы процессов, что и отправитель. Группа процессов, отличная от текущей, может быть обозначена с помощью kill(-PGID) (или kill -- -PGID в оболочке), где PGID — это идентификатор группы процессов.

Группа процессов PID возвращается функцией getpgid(), а группу процессов текущего процесса можно найти с помощью getpgrp().

В оболочке вы можете использовать

$ ps -opid,pgid,command

для получения PID, PGID (идентификатор группы процессов) и командной строки вашего текущего сеанса.

Это может вернуть что-то вроде

  PID  PGID COMMAND
20716 20716 -ksh93 (ksh93)
83662 83662 -ksh93 (ksh93)
 4322  4322 /usr/X11R6/bin/xclock
 5374  5374 tmux: client (/tmp/tmux-11000/default) (tmux)
78747 78747 -ksh93 (ksh93)
29298 29298 ps -opid
63563 63563 -ksh93 (ksh93)
63327 63327 mutt
21790 21790 -ksh93 (ksh93)
64493 64493 /bin/sh /usr/X11R6/bin/startx
14485 64493 xinit /home/kk/.xinitrc -- /usr/X11R6/bin/X :0 -auth /home/kk/.serverauth.E3cwuT5FZR
93531 93531 sh /home/kk/.xinitrc
48598 93531 flwm
28154 93531 xterm
73053 93531 xterm

После уточнения вопроса:

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

Без концепции группы процессов нужно было бы получить все процессы в системе, выяснить, как они связаны (используя идентификаторы родительских процессов) и выполнить итерацию по соответствующим процессам, посылая каждому сигнал.

Ядро делает это, но оно знает и отслеживает группы процессов, поэтому ему никогда не придется перебирать все процессы, чтобы послать сигнал группе процессов, только по членам группы .

Поскольку идентификатор группы процессов открывается для пользователя, достаточно будет запросить идентификатор группы процессов только у одного процесса, прежде чем можно будет отправить сигнал всем процессам в эта группа.

0
30.03.2017, 02:07
5 ответов

Perl

perl -pale '$_ = join $", $F[0], join(",", $F[1] =~ /AA\d{7}/g), @F[2..$#F]' yourfile

Bash

Использование cat здесь намеренно, поскольку мы не хотим разрушать позиционное параметры ($ 1, $ 2, ..., $ #) и, следовательно, запуск цикла while в подоболочке.

cat yourfile |
while read -r f1 f2 rem; do
   set -- "$f1" "$(printf '%s\n' "$f2" | grep -oP 'AA\d{7}' | paste -sd,)" "$rem"
   printf '%s\n' "$*"
done

Sed

sed -e '
   s/[^ ]*[ ]*/&\
\
/
   s/AA[0-9]\{7\}/\
&\
/g

   :loop
      s/\nAA[0-9]\{7\}\(\n\)/\1&/
      s/\n\n.*\(\n\n\)/\1/
      s/\(\n\n\)\(AA[0-9]\{7\}\)\n/\2,\1/
   /\nAA[0-9]\{7\}\n/bloop

   s/,\n\n[^ ]*//
' yourfile
1
28.01.2020, 02:13

sed может это сделать. Мы можем использовать 4 совпадающие группы, чтобы найти префикс, суффикс и два идентификатора посередине.

Код:

sed -rn 's/([^ ]+) .*(AA[0-9]{7}).*(AA[0-9]{7}).* ([^ ]+)/\1 \2,\3 \4/p' file1

Данные испытаний:

Text1 somethingAA0123456something,elseAA6543210foo text1
Text2 somethingAA1234567something,elseAA7654321foo text2
Text3 somethingAA2345678something,elseAA8765432foo text3

Результаты:

Text1 AA0123456,AA6543210 text1
Text2 AA1234567,AA7654321 text2
Text3 AA2345678,AA8765432 text3
2
28.01.2020, 02:13

Решение Bash для обновленного запроса:

echo "$b"
#Output
Text1 somethingAA1111111something,elseAA2222222fooblahAA3333333^blahblahAA4444444 text1
Text2 somethingAA1111111something,elseAA7777777fooblahAA5454545^blah text2
Text3 somethingAA1111111something,elseAA2222222foo text3

while IFS=" " read -r f1 f2 f3;do 
  g=($(grep -Po 'AA[0-9]{7}' <<<"$f2"));
  out=$(printf '%s,%s,%s\n' "$f1" "${g[*]}" "$f3");
  echo "$out" |sed 's/,/\x00/g; s/ /,/g; s/\x00/ /g';
done <<<"$b"
#Output
Text1 AA1111111,AA2222222,AA3333333,AA4444444 text1
Text2 AA1111111,AA7777777,AA5454545 text2
Text3 AA1111111,AA2222222 text3
2
28.01.2020, 02:13

awk решение:

$ a="Text1 somethingAA0123456something,elseAA9876543foo text1"
$ awk -F"[ ,]" '{match($2,/(AA[0-9]{7})/,a);match($3,/(AA[0-9]{7})/,b);print $1,a[1],",",b[1],$NF}' <<<"$a"
Text1 AA0123456,AA9876543 text1

Также это работает:

$ awk '{match($0,/(\w+\s)(\w+)(\w\w[0-9]{7})(\w+,\w+)(\w\w[0-9]{7})(\w+\s)(\w+)/,a);print a[1],a[3],",",a[5],a[7]}' <<<"$a"

ОБНОВЛЕНИЕ
Для ваших новых требований и с GNU awk вы можете использовать что-то вроде этого:

$ echo "$b"
Text1 somethingAA1111111something,elseAA2222222fooblahAA3333333^blahblahAA4444444 text1
Text2 somethingAA1111111something,elseAA7777777fooblahAA5454545^blah text2
Text3 somethingAA1111111something,elseAA2222222foo text3

$ awk '{gsub(/(AA[0-9]{7})/," & ",$2)}1' <<<"$b" |awk '{printf("%s ",$1);for (i=2;i<NF;i++) {if($i ~ /AA[0-9]+/) printf("%s%s",$i,(i==NF-1)?" ":",")}}{printf(" %s\n",$NF)}'
Text1 AA1111111,AA2222222,AA3333333,AA4444444  text1
Text2 AA1111111,AA7777777,AA5454545, text2
Text3 AA1111111,AA2222222, text3

Единственная ловушка, которая есть лишняя запятая в некоторых записях после последнего AAXXXXXXX . Надеюсь, это не большая проблема.

Это решение объединяет два файла awk. Первый awk преобразует каждую строку, вставляя пробел перед и после каждого найденного AAXXXXXXX:

$ echo "$a"
Text2 somethingAA1234567something,elseAA0987654fooblahAA3333333^blah text2
$ awk '{gsub(/(AA[0-9]{7})/," & ",$2)}1' <<<"$a"
Text2 something AA1234567 something,else AA0987654 fooblah AA3333333 ^blah text2

Эти преобразованные записи затем передаются второму awk, который печатает первое поле, последнее поле и промежуточные поля, которые соответствуют шаблон AAXXXXXXX

2
28.01.2020, 02:13

perl. Аналогично подходу sed. Протестируйте строку на соответствие длинному регулярному выражению, захватив соответствующие нужные части строки в $1, $2, $3, $4. Создайте ответ в $_, чтобы он был напечатан благодаря флагу '-p'.

$ perl -pe 'if(/^(Text\d+) .*(AA\d{7}).*(AA\d{7}).* (.*)/){$_="$1 $2,$3 $4$/"}' file1
Text1 AA0123456,AA6543210 text1
Text2 AA1234567,AA7654321 text2
Text3 AA2345678,AA8765432 text3
$
2
28.01.2020, 02:13

Теги

Похожие вопросы