замените пустые поля в выводе «grep» строкой

Из статьи Википедии о демонах :

В среде Unix родительский процесс демона часто, но не всегда, является процессом инициализации. Демон обычно создается либо процессом, разветвляющим дочерний процесс, а затем немедленно завершающимся, что заставляет init принять дочерний процесс, либо процессом init, непосредственно запускающим демон. Кроме того, демон, запускаемый путем разветвления и выхода, обычно должен выполнять другие операции, такие как отключение процесса от любого управляющего терминала (tty). Такие процедуры часто реализуются в различных вспомогательных подпрограммах, таких как daemon (3) в Unix.

Прочтите справочную страницу функции демона .

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

# bash -c 'nohup sleep 10000 &>/dev/null & jobs -p %1'
1936
# ps -p 1936
      PID    PPID    PGID     WINPID   TTY         UID    STIME COMMAND
     1936       1    9104       9552  cons0       1009 17:28:12 /usr/bin/sleep

Как видите, процесс принадлежит PID 1, но все еще связан с TTY. Если я выйду из этой оболочки входа, затем снова войду и снова сделаю ps , TTY станет ? .

Прочтите, почему важно отключиться от TTY .

Использование setsid (часть util-linux ):

# bash -c 'cd /; setsid sleep 10000 /dev/null & jobs -p %1'
9864
# ps -p 9864
      PID    PPID    PGID     WINPID   TTY         UID    STIME COMMAND
     9864       1    9864       6632  ?           1009 17:40:35 /usr/bin/sleep

Я думаю, вам даже не нужно перенаправлять stdin, stdout и stderr.

-1
12.05.2017, 19:28
4 ответа
while read -r line; do
  date=$(grep -Eo  "201.{12}.M," <<< "$line")
  phrase=$(grep  -Eo "certain phrase" <<< "$line")
  echo "${date}${phrase:-NULL}"
done < test.txt

Вы читали строку, но не искали ее. Я подправил регулярное выражение в первом grep, чтобы оно соответствовало дате (вместо -c ее подсчета). Последней частью головоломки было отображение переменной $phrase с расширением параметра, чтобы заменить пустое значение словом «NULL».

2
29.04.2021, 00:01

Вместо grepping в while выполните все в одном sed скрипте:

sed 's/\( *[0-9]*,[^,]*,\).*\(certain phrase[^ ]*\).*/\1\2/;t
  s/\( *[0-9]*,[^,]*,\).*/\1NULL/' file.txt

sed уже обрабатывает за вас построчно, и в каждой строке скрипт выполняет замену командой s:

Первая часть [0-9]*, [^,]*, должно соответствовать строке даты. Окружая его \(\), мы можем повторно использовать его в замене как \1

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

Если эта замена была сделана, команда t переходит в конец скрипта, как мы и сделали. Если замена невозможна, все после даты заменяется на NONE

2
29.04.2021, 00:01

Я бы предложил что-то вроде

awk 'BEGIN {OFS=FS=","} 
  /201/ {
    if (match($0,"certain phrase")) {
      print $1, $2, substr($0,RSTART,RLENGTH+1)
    } else {
      print $1, $2, "NULL"
    }
  }' file

Тестирование с вашими входными данными:

$ awk 'BEGIN {OFS=FS=","} 
>   /201/ {
>     if (match($0,"certain phrase")) {
>       print $1, $2, substr($0,RSTART,RLENGTH+1)
>     } else {
>       print $1, $2, "NULL"
>     }
>   }' file
 20170101,05:00 AM,certain phrase1
 20170102,09:30 AM,certain phrase2
 20170103,05:30 AM,NULL
2
29.04.2021, 00:01
perl -lne 'print /^((?:.+?,){2})/, /\h\K(certain\h+phrase\d+)/ ? $1 : "NULL"' < test.txt

Здесь мы получаем первые два поля, разделенные запятыми, а затем ищем "определенная фраза". Если он найден, используйте его, иначе используется «NULL».

0
29.04.2021, 00:01

Теги

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