Хорошие ответы здесь, но если предположить, что не каждая строка заканчивается пробелом (, например, если у вас есть некоторые, которые действительно попадают в ваш "=" ), вы можете использовать это:
grep -c "^1[^0-9]" file
В основном это соответствует любой строке, которая начинается с единицы, за которой следует цифра, отличная от -, включая пробелы. Немного более подробный, но и более надежный. (Хотя стоит отметить, что здесь нет ничего для нулевого условия всего -одного -на -строке -, это не зависит от конца -из -строки.)
С оболочкой zsh
можно сделать:
print -rC1 Ion_<3-5>_rawlib.bam
Где <x-y>
— это оператор глобуса, который сопоставляется с текстовыми десятичными представлениями положительных целых чисел в заданном диапазоне (от x
до y
, включая ).
Рекурсивно:
print -rC1 -- **/Ion_<3-5>_rawlib.bam
(добавьте (D)
, если вы также хотите искать эти файлы в скрытых папках, или (N)
, если вы не хотите считать это ошибкой, когда нет подходящего файла ).
С find
реализациями, поддерживающими предикат -regex
, вы можете сделать:
LC_ALL=C find. -regex '.*/Ion_0*[345]_rawlib\.bam'
(соответствует путям к файлам, состоящим из 0 или более(*
)байтов(.
с LC_ALL=C
), за которым следует /Ion_
, за которым следует 0 или более(*
)0
s, за которыми следует один из 3
, 4
или 5
символов, за которыми следуетrawlib.bam
).
Здесь это относительно просто для диапазона 3..5, но будет гораздо более болезненным для таких диапазонов, как, например, 78..123 (, и вы столкнетесь с проблемами совместимости, так как несколько реализаций find
которые поддерживают -regex
, используют различные форматы регулярных выражений ).
Стандарт find
поддерживает только -name
и -path
для сопоставления имен файлов, и это делается с помощью базовых подстановочных знаков оболочки, а не регулярных выражений, но подстановочные знаки не имеют эквивалента *
оператора регулярного выражения (0 или более предшествующего атома ), его оператор *
эквивалентен регулярному выражению.*
(0 или более символов ), поэтому Ion_*[3-5]_rawlib.bam
будет соответствовать Ion_9994_rawlib.bam
, например, как *
соответствует на 999
.
Однако в этом простом случае вы можете сделать это, используя несколько шаблонов и отрицаний, таких как:
LC_ALL=C find. -name 'Ion_*[345]_rawlib.bam' \
! -name 'Ion_*[!0]*?_rawlib.bam'
Не -рекурсивно:
LC_ALL=C find. ! -name. -prune \
-name 'Ion_*[345]_rawlib.bam' \
! -name 'Ion_*[!0]*?_rawlib.bam'
Чтобы найти файлы, содержащие десятичные представления целых чисел от x
до y
в любом месте имени, вам нужен шаблон, соответствующий этому диапазону (, например zsh
's <x-y>
), но также убедитесь, что шаблон не окружен другими цифрами. Например, foo305.txt
содержит 3
, 05
и 5
, все из которых соответствуют <3-5>
.
В zsh
это будет:
print -rC1 -- (|*[^0-9])<3-5>(|[^0-9]*)
То есть <3-5>
(, что соответствует 3, 03, 003... )либо после ничего, либо за строкой, заканчивающейся цифрой, отличной от -, за которой следует либо ничего, либо строка, начинающаяся с не -. ] цифра.
С BSDfind
:
LC_ALL=C find -E. -regex '.*/([^/]*[^0-9])?0*[3-5]([^0-9][^/]*)?'
С GNU find
то же самое, но замените -E.
на . -regextype posix-extended
.
С busybox find
(, хотя зависит от того, как он был скомпилирован):
busybox find. -regex '.*/\([^/]*[^0-9]\)\?0*[3-5]\([^0-9][^/]*\)\?'
Другой подход состоит в том, чтобы использовать find
для создания списка файлов, но использовать более продвинутые языки, такие как perl
, для фильтрации этого списка:
find. -print0 | perl -l -0ne '
if (m{[^/]*\z}) {
for $n ($& =~ /\d+/g) {
if ($n >= 3 && $n <= 5) {
print;
next LINE;
}
}
}'
Здесь используется perl
для извлечения всех последовательностей десятичных цифр из базового имени каждого файла и вывода файлов, если хотя бы одна из этих последовательностей цифр представляет число в диапазоне 3..5.