
Я пытаюсь использовать sed
команду для поиска в файле всех записей 10000 и ниже, но думаю, что эта неполная sed
строка поиска может относиться к записям 10000 и выше:
sed -n "/[0-9][0-9][0-9][0-9][0-9]/ q" logfile
решение1
Вы также можете сделать это следующим способом:
$ sed -n "/^[0-9]\{0,4\}$\|10000/p" logfile
Пример
Допустим, у меня есть файл-образец, logfile
например такой:
$ seq 9900 10050 | sed 's/$/ /' > logfile
В результате файл logfile
будет выглядеть следующим образом:
$ head -5 logfile
9900
9901
9902
9903
9904
$ tail -5 logfile
10046
10047
10048
10049
10050
После каждой из этих строк есть завершающий пробел, поскольку это произошло, sed 's/$/ /'
когда мы создавали файл-образец в строке выше.
Теперь, когда мы выполним указанную выше sed
команду:
$ sed -n "/^[0-9]\{1,4\}[^0-9]\|10000/p" logfile | tail -5
9996
9997
9998
9999
10000
Мы получаем все до 10000, и ничего больше.
Как это работает
Вышеуказанное sed
работает путем поиска строк, начинающихся с диапазона цифр 0-9, длиной от 1 до 4. Нотация to sed
выполняет "/^[0-9]\{1,4\}[^0-9]
эту часть. Нотация [^0-9]
в конце там говорит о символах, которые не являются 0-9. Это останавливает sed
сопоставление подстрок в числах, которые длиннее.
Соответствует \|10000
10000, так как это немного уникальный шаблон по сравнению с остальными строками до него. Завершающий p
говорит о sed
необходимости вывести результаты.
Использование grep в качестве альтернативы
Использование sed
не совсем правильный инструмент для поиска. Вам, вероятно, лучше использовать grep
для этого.
$ grep "\b\([0-9]\{1,4\}\|10000\)\b" logfile | head -5
9900
9901
9902
9903
9904
$ grep "\b\([0-9]\{1,4\}\|10000\)\b" logfile | tail -5
9996
9997
9998
9999
10000
Вышеприведенный код найдет все строки, содержащие строку цифр, равную или меньшую 10000. Обозначает \b
границу либо до, либо после строки.
решение2
Perl может сделать это проще и более читабельным:
perl -nE 'say for grep { $_ <= 10_000 } /([0-9]+)/g' your_file
решение3
sed '/[0-9]/!d;/10000/q' <log.file
Пока записи идут в последовательном порядке, вам нужно только указать, что строка содержит число, !
иначе d
удалите его. И когда вы дойдете до строки, 10000
вы q
удалите. Но 10000 все равно будет напечатано — это будет последняя напечатанная строка.
Было бы намного лучше, если бы вы могли прикрепить его, например, к началу строки, например:
sed '/^[0-9]/!d;/^10000/q' <log.file
Что было бы надежнее и быстрее.
Но, как отмечает slm, grep
это было бы быстрее.
решение4
sed -nr "/0|[1-9][0-9]?[0-9]?[0-9]?[0-9]?/p" logfile