Извлечь значение в строке после сопоставления с образцом

Вы можете направить результат через соответствующий -постпроцессор. Вот один, который я написал в sed:

#!/bin/sed -f

# Move any null into hold space
/^$/{
H
d
}

# Insert nulls after last line
$G
# Delete an extra newline this introduces
$s/\n//

Если ваш sortдействительно пишет <NULL>, а не пустую строку, вам нужно изменить шаблон /^$/на /^<NULL>$/.

Демо

sort -g <<EOF |./475768.sed 
0.9000
23
      
1
2     
5
  
-0.9000
-23
 
-1
-2
-5
EOF
-23
-5
-2
-1
-0.9000
0.9000
1
2
5
23


 
2
07.01.2021, 16:37
5 ответов

Здесь 2 ошибки :круглые скобки и косая черта должны быть экранированы. В общем, должно быть:

awk '/kappa \(ts\/tv\) =/ {print $NF}' text.txt
3
18.03.2021, 22:38

У вас тут две проблемы. Во-первых, оператор сопоставления использует /в качестве разделителя. Однако искомый шаблон также содержит /. Это означает, что это:

/kappa (ts/tv) =/

Интерпретируется как /kappa (ts/, а затем tv) =/, что приводит к синтаксической ошибке. Вам нужно выйти из /и сделать это \/. Далее, круглые скобки имеют особое значение в контексте регулярных выражений (в некоторых разновидностях регулярных выражений, в любом случае ):они используются для захвата совпадающей группы. Таким образом, они также должны быть экранированы, чтобы делать то, что вы хотите. Все это вместе дает:

awk '/kappa \(ts\/tv\) =/{print $NF}' text.txt
7
18.03.2021, 22:38

Ваш вопрос недостаточно ясен, и мой ответ основан на ваших высказываниях:

"extract the value in a Nth line after the matching pattern..."

awk -v line_num_after_match=1 '
    NR==seen+line_num_after_match && seen { print; seen=0; };
    /kappa \(ts\/tv\) =/ && !seen { seen=NR; }' infile

работает на входе ниже:

line 1
line 2
line 3
line 4: kappa (ts/tv) =
line 5: another kappa (ts/tv) = but line 1 after match
line 6: but line 2 after first match and line 1 after second match
line 7: but line 3 after first match and line 2 after second match
line 8: yet another kappa (ts/tv) =
line 9: xxxxxxxx

возвращает:

line 5: another kappa (ts/tv) = but line 1 after match
line 6: but line 2 after first match and line 1 after second match
line 9: xxxxxxxx
3
18.03.2021, 22:38

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

$ cat file
1
2
kappa (ts/tv) =
4
5
6
7
8
9

вы можете использовать index()для частичного совпадения строки вместо частичного совпадения регулярного выражения, которое вы делали:

$ awk -v n=5 'c&&!--c; index($0,"kappa (ts/tv) ="){c=n}' file
8

$ awk -v n=2 'c&&!--c; index($0,"kappa (ts/tv) ="){c=n}' file
5

или используйте $0 == "kappa (ts/tv) ="вместо index($0,"kappa (ts/tv) ="), если вы хотите полное соответствие строки -.

См.https://stackoverflow.com/questions/17908555/printing-with-sed-or-awk-a-line-following-a-matching-pattern/17914105#17914105для получения дополнительной информации о том, как напечатать строку после совпадения.

2
18.03.2021, 22:38

команда sed

sed -n '/kappa (ts\/tv) =/p' filename

Питон

#!/usr/bin/python
import re
l=re.compile(r'kappa \(ts\/tv\) =')
m=open('filename','r')
for h in m:
    if re.search(l,h):
        print h.strip()

~

0
18.03.2021, 22:38

Теги

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