grep до 3 пробелов с \ s
Согласно следующим руководствам
- https://linuxize.com/post/regular-expressions-in-grep/
\ s Соответствует пробелу.
и
- https://www.guru99.com/linux-regular-expressions.html
Некоторые интервальные регулярные выражения:
Описание выражения
{n} Соответствует предыдущему символу, который встречается n раз точно.
{n, m} Соответствует предыдущему символу, встречающемуся n раз, но не более m
{n,} Соответствует предыдущему символу, только если он встречается n раз или более
Образец файла
wolf@linux:~$ cat space.txt 0space 1 spaces 2 spaces 3 spaces 4 spaces wolf@linux:~$
Я просто хочу использовать grep только до 3 пробелов, минимум 1 пробел, максимум 3 пробела. К сожалению, на самом деле это не работает так, как ожидалось.
wolf@linux:~$ cat space.txt | grep -P '\s{1,3}' 1 spaces 2 spaces 3 spaces 4 spaces wolf@linux:~$
wolf@linux:~$ cat space.txt | grep -P '\s{3}' 3 spaces 4 spaces wolf@linux:~$
wolf@linux:~$ cat space.txt | grep -P '\s{3,3}' 3 spaces 4 spaces wolf@linux:~$
wolf@linux:~$ cat space.txt | grep -P '\s{0,3}' 0space 1 spaces 2 spaces 3 spaces 4 spaces wolf@linux:~$
Желаемый результат
wolf@linux:~$ cat space.txt | grep -P '\s{0,3}' <- need to fix it here 1 spaces 2 spaces 3 spaces wolf@linux:~$
Ответы
тебе нужно:
grep -P '\S\s{1,3}\S' infile
\sсоответствует пробелу, а не только пробелу.
\Sсоответствует непробельному символу
в вашей попытке вы не ограничиваете, чтобы до и после ваших совпадений не было пробелов.
чтобы фильтровать только пространство и избегать использования PCRE, вы можете:
grep '[^ ] \{1,3\}[^ ]' infile
или для работы со строками, имеющими ведущие / конечные 1 ~ 3 пробела:
grep '\([^ ]\|^\) \{1,3\}\([^ ]\|$\)' infile
входные данные ( cat -e infile):
0space$
1 spaces$ 2 spaces$
3 spaces$ 4 spaces$
3spaces$ 4space$
3spaces $ 4spaces $
вывод:
1 spaces$ 2 spaces$
3 spaces$ 3spaces$
3spaces $
Если вы хотите сопоставить последовательность от 1 до 3 пробельных символов, не окруженных пробелами, вам следует использовать операторы просмотра Perl:
grep -P '(?<!\s)\s{1,3}(?!\s)'
Соответствует:
1
1234567890123456789
a b c d e
^ ^^ ^^^
Со стандартом grepвы можете добиться того же эффекта с помощью:
grep -E '(^|[^[:space:]])[[:space:]]{1,3}([^[:space:]]|$)'
На этот раз мы сопоставляем последовательность от 1 до 3 пробельных символов и непробельные символы с обеих сторон (или start ( ^) или end ( $) темы).
1
1234567890123456789
a b c d e
^^^^ ^^^^
(с -o(расширением GNU) вы обнаружите, что он не сообщает, a bчто aуже было сопоставлено ранее; при поиске дополнительных совпадений он начинается со следующего символа после последнего совпадения).
Без них -Eвы получаете базовые регулярные выражения, в которых нет операторов чередования (хотя некоторые grepреализации поддерживают \|это как расширение), но стандартно вы все равно можете:
grep -x '\(.*[^[:space:]]\)\{0,1\}[[:space:]]\{1,3\}\([^[:space:]].*\)\{0,1\}'
На этот раз регулярное выражение соответствует всей строке, включая от 1 до 3 пробелов и необязательную ( \{0,1\}эквивалент ERE ?) ведущую часть, заканчивающуюся непробельным символом, и необязательную часть, следующую за ней, которая начинается с непробельного символа.
1
1234567890123456789
a b c d e
^^^^^^^^^^^^^^^^^^
В любом случае, они все равно будут возвращать строки, содержащие последовательность из 4 или более пробелов, если они также содержат последовательность от 1 до 3 пробелов, не окруженных пробелами.
Если бы целью было исключить строки, содержащие последовательности из 4 или более пробелов, то это было бы просто:
grep -vE '[[:space:]]{4}'
Или, если вам все еще нужен хотя бы один пробел, или, другими словами, строка содержит одну или несколько последовательностей пробельных символов, каждая из которых имеет хотя бы один пробел, но не более 3:
grep -vE -e '[[:space:]]{4}' -e '^[^[:space:]]*$'
То есть вернуть все строки, кроме тех, которые содержат последовательность из 4 пробелов, и тех, которые сделаны исключительно из непробелов.
Или снова с операторами просмотра Perl:
grep -P '^(?=.*\s)(?!.*\s{4})'
Это соответствует началу строки при условии, что за ним следует любое количество символов и пробел и что за ним не следует какое-либо количество символов и последовательность из 4 пробелов.
Хотя было бы более разборчиво с sedили awkгде вы можете сделать как положительное, так и отрицательное совпадение в одном вызове:
awk '/[[:space:]]/ && ! /[[:space:]]{4}/'
sed '/[[:space:]]/!d; /[[:space:]]\{4\}/d'
Можно подойти с противоположного. Исключить строки с более чем 3 пробелами в подстроке.
grep -Ev '\s{4,}'
-vИзмените смысл соответствия, чтобы выбрать несовпадающие строки.
Вы можете вставлять якоря как непробельные символы
grep -E '\S\s{1,3}\S'