Печать до (включительно) n-го появления шаблона в строке

Если вы используете 'File' и 'Open', Geany откроет файл в текущем "основном" экземпляре, т.е. в том экземпляре Geany, который вы используете в данный момент, а не в первом.

3
13.04.2016, 00:19
3 ответа

При использовании POSIX grep вы можете выбирать только между печатью всей строки или не печатать содержимое строки вообще. Если вы хотите преобразовать строку, вам нужно использовать другой инструмент, например sed или awk. Для печати до первого вхождения cat:

sed -n 's/cat.*/cat/'
awk 'sub(/cat.*/,"")'

Печать до Nого вхождения сложнее.

sed -n 's/cat/&\
/3; T; P'
awk 'gsub(/cat/,"&\n") >= 3 {split($0, a, "\n"); printf "%s%s%s\n", a[1], a[2], a[3]}'

В GNU grep вы можете использовать опцию -o для печати только совпавшей части строки. Используйте опцию -P для активации синтаксиса Perl, чтобы были доступны нежадные квантификаторы.

grep -P -o '^(.*?cat){1}'

Замените число в скобках на число n последнего вхождения cat для печати.

Хотя то же самое можно выразить с помощью расширенных регулярных выражений (-E), это требует сложного regexp, размер которого экспоненциально зависит от размера части, которую нужно посчитать (cat здесь).

2
27.01.2020, 21:22

Вот sed решение (например, печатать до 2-го вхождения включительно; заменить 2 на ваш номер. ):

sed -n 's/cat/&\
/2
t print
d
:print
P' infile

Это отключает автопечать через -n и пытается заменить второе вхождение cat на cat+ символ новой строки. При успешной замене происходит ветвление на :print и Prints до новой строки, иначе строка deleted.


С помощью gnu sed вы можете записать это как одну строку (например, напечатать до 5-го вхождения включительно):

sed -n 's/cat/&\n/5;tt;d;:t;P' infile
0
27.01.2020, 21:22

grep только выбирает строки на основе заданного регулярного выражения и печатает их.

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

Обычно вы используете sed или awk, чтобы сделать эту работу без grep, потому что они могут и выбирать строки, и заменять строки.

Ниже приведено решение с использованием awk:

awk -v word=cat -v n=2 'BEGIN {wordlength=length(word);} {line=$0;outputline="";position=index(line,word);for (i=1;position>0 && i<=n; i++) { outputline=outputline substr(line,1,position+wordlength-1);line=substr(line,position+wordlength);position=index(line,word);  } if (i!=1) {print outputline;}}'

Вы должны задать word строку для поиска, а n - желаемое количество вхождений.

The test:

$ awk -v word=cat -v n=2 'BEGIN {wordlength=length(word);} {line=$0;outputline="";position=index(line,word);for (i=1;position>0 && i<=n; i++) { outputline=outputline substr(line,1,position+wordlength-1);line=substr(line,position+wordlength);position=index(line,word);  } if (i!=1) {print outputline;}}' file
Turbo is a cat. cat
Coco is a black cat. cat
1
27.01.2020, 21:22

Теги

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