Я пытаюсь найти строку с двузначным числом, например:

Test.txt

uuLinuxxx
Linux 2011
2011 Linux RedHat
Linux RedHat
2011
2013  2014
2010
/usr/bin
2
Ubuntu 20 world

Желаемый OP: мир Ubuntu 20

Я использую

sed -n '/[0-9]\{2\}/p' test.txt

Но проблема в том, что он печатает все строки с двузначным числом.

2
Shashank Vivek 7 Мар 2014 в 09:42

4 ответа

Лучший ответ

Это может сработать для вас (GNU sed):

sed -n '/\b[0-9]\{2\}\b/p' file

Или же:

sed -nr '/\b[0-9]{2}\b/p' file

Или же:

sed -r '\b[0-9]{2}\b/!d' file

Или же:

sed '/\<[0-9]\{2\}\>/!d' file
5
potong 7 Мар 2014 в 11:59

Используйте переключатель -w для соответствия слову (в вашем случае - цифрам).

grep -w '[0-9][0-9]' file

Со страницы man:

-w, --word-regexp
     Select only those lines containing matches that form whole words.  
     The test is that the matching substring must either be at the beginning of the
     line,  or preceded by a non-word constituent character. Similarly, it must be either 
     at the end of the line or followed by a non-word constituent character. Word-
     constituent characters are letters, digits, and the underscore.
2
jaypal singh 7 Мар 2014 в 07:09

Проблема в том, что ваше регулярное выражение ищет две последовательные цифры, среди которых есть числа 20 (хорошо) и 99999999999999999999 (не очень хорошо).

Что вам нужно, так это регулярное выражение, обеспечивающее отсутствие цифр по обе стороны от двух, которые вы найдете, например:

[^0-9][0-9]{2}[^0-9]  # non-digit the two digits then non-digit

Кроме того, вам нужно перехватить те, где две цифры находятся в начале или конце строки (или единственном элементе в строке). Поэтому вам нужно несколько регулярных выражений, разделенных союзом или |, или отдельными аргументами -e:

^[0-9]{2}[^0-9]       # at start of line
[^0-9][0-9]{2}[^0-9]  # in middle of line
[^0-9][0-9]{2}$       # at end of line
^[0-9]{2}[^0-9]$      # only thing on line

Вы также можете выбрать лучший инструмент для работы, например grep. Используя слегка измененный входной файл:

uuLinuxxx
Linux 2011
2011 Linux RedHat
Linux RedHat
2011
2013  2014
2010
/usr/bin
2
Ubuntu 20 world
99 at the start
at the end: 99
88

Следующая команда (разделить для удобства чтения):

grep -E -e '[^0-9][0-9]{2}[^0-9]'
        -e '^[0-9]{2}[^0-9]'
        -e '[^0-9][0-9]{2}$'
        -e '^[0-9]{2}[^0-9]$' test.txt

Дает вам то, что вы хотите:

Ubuntu 20 world
99 at the start
at the end: 99
88

Конечно, если у вас есть GNU grep с его регулярными выражениями на основе Perl, и вы ищете «слова», которые являются двузначными числами, это станет намного проще:

grep -P '\b\d{2}\b' test.txt

Но, если вы можете гарантировать это ограничение слов, следующее также будет работать:

grep -Ew '[0-9]{2}' test.txt
1
paxdiablo 7 Мар 2014 в 06:44
sed -n 's/.*/²&²/;/[^0-9][0-9]\{2\}[^0-9]/ s/.\(.*\)./\1/p' YourFile

Использование временной рамки, чтобы разрешить только одну проверку для извлечения строки с двухзначным числом внутри

1
NeronLeVelu 7 Мар 2014 в 07:05