Вставьте новую строку со значением, если значение вообще не найдено

Вставьте новую строку со значением, если значение вообще не найдено

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

Я хотел бы получить вывод другой команды, который выглядит примерно так:

pattern.d
17.91
17.55
pattern.b
pattern.a
7.21
9.34
pattern.c

к этому:

pattern.d
17.91
17.55
pattern.b
1000
pattern.a
7.21
9.34
pattern.c
1000

Я попытаюсь объяснить немного больше: После каждой строки, содержащей строку "pattern", всегда должно быть число. Если нет, я хотел бы вставить новую строку со значением 1000.

Обратите внимание, что у шаблона есть «расширение» (.a .b .c .d, но в «расширении» нет цифр), которое меняется, и это поможет мне позже отсортировать содержимое в алфавитном порядке.

EDIT: Я принял ответ, но на случай, если кто-то все еще хочет поискать другой вариант, я должен указать, что встречаемость «шаблона» варьируется, и может быть более 2 или 3 последовательных вариантов, как в:

pattern.a
pattern.d
pattern.c
pattern.d
pattern.b
17.91

решение1

Вот sedрешение, которое будет работать с любыми входными данными (например, с несколькими последовательными строками, соответствующими pattern):

sed '1{                   # when on first line
x                         # exchange
s/^/1000/                 # replace the empty hold buffer with "1000"
x                         # exchange back
}
: do                      # label "do"
/pattern/{                # if the current line matches "pattern"
${                        # if we're on the last line
G                         # append hold buffer content to pattern space
b                         # go to end of script
}
n                         # otherwise print and pull in the next line
/^[[:digit:]]/!{          # if this one doesn't start with a digit
x                         # exchange
p                         # print (the pattern space is now "1000")
x                         # exchange back
b do                      # go to label "do"
}
}' infile

С gnu sedним можно записать как

sed '1{x;s/^/1000/;x};:b;/pattern/{${G;b};n;/^[[:digit:]]/!{x;p;x;bb}}' infile

Вы можете сделать что-то подобное с помощью awk:

awk -vc=0 '!/^[[:digit:]]/{
if (c) {print "1000"}
}
{ if (/pattern/){c=1} else{c=0}
}
END{if (c){print "1000"}
};1' infile

то есть, установить c=1на совпадающих строках patternи c=0на остальных строках, а также на каждой строке, которая не начинается с цифры (а также в блоке END), проверить, cустановлен ли (или 1- что означает, что предыдущая строка совпадает pattern) - если да, вывести 1000.

решение2

sed -e '
   $!{
      /pattern\.[a-z]/N
      /\n/!b
      /\n[+-]\{0,1\}[.][0-9]\{1,\}$/b
      /\n[+-]\{0,1\}[0-9]\{1,\}\([.][0-9]*\)\{0,1\}$/b
      h;s/\(.*\n\).*/\11000/p
      g;D
   }
   /pattern\.[a-z]/a\
1000
' yourfile

Полученные результаты

pattern.d
17.91
17.55
pattern.b
1000
pattern.a
7.21
9.34
pattern.c
1000

Работающий

  • Пока мы не достигли конца файла, $!{...}мы добавляем следующую строку в пространство шаблона при условии, что текущая строка представляет интерес.
  • Затем мы пропускаем дальнейшую обработку в случаях: а) Не найдена новая строка => нет шаблона в текущей строке. б) Число с плавающей точкой формата .nnn во второй строке. в) Число с плавающей точкой формата mmm, mmm. или mmm.nnn найдено исключительно во второй строке. г) Исключая любую из возможностей => нам нужно добавить магическое число 1000 в конец следующей строки после новой строки.

решение3

Если никогда не встречается более двух последовательных экземпляров pattern, и у вас есть GNU sed, то:

sed '/^pattern/ {$!N; /\n[0-9]/b; s/$/\n1000/M}' file
pattern.d
17.91
17.55
pattern.b
1000
pattern.a
7.21
9.34
pattern.c
1000

Как это работает:

  • если текущая строка начинается с patternто
    • если мы не достигли EOF, добавьте следующую строку
    • если после символа новой строки стоит цифра (это можно сделать более конкретно), то bпереходим на следующую строку; в противном случае
    • замените первую строку, заканчивающуюся новой строкой и1000

Модификатор , специфичный для GNU, Mпозволяет $сопоставлять либо \nлибо , $так что он обрабатывает как «нормальный» случай, так и случай EOF, когда последующая строка не добавляется.

решение4

awkрешение:

awk '{ if ($0 ~ /pattern/) {      # if it's a `pattern` line
         if ((getline nl) > 0) {  # check if next record exists
             # if next record hasn't number - insert `1000`, otherwise - print current and next records as they are
             print ((nl !~ /^[0-9]/)? $0 ORS 1000 ORS nl: $0 ORS nl)
         } else {
             print $0 ORS 1000   # if the file ends up with pattern - insert `1000`
         } 
       } else {
          print $0  # print other record
       }
    }' file

Выход:

pattern.d
17.91
17.55
pattern.b
1000
pattern.a
7.21
9.34
pattern.c
1000

Связанный контент