Найти имена файлов, содержащие число

Хорошие ответы здесь, но если предположить, что не каждая строка заканчивается пробелом (, например, если у вас есть некоторые, которые действительно попадают в ваш "=" ), вы можете использовать это:

 grep -c "^1[^0-9]" file

В основном это соответствует любой строке, которая начинается с единицы, за которой следует цифра, отличная от -, включая пробелы. Немного более подробный, но и более надежный. (Хотя стоит отметить, что здесь нет ничего для нулевого условия всего -одного -на -строке -, это не зависит от конца -из -строки.)

1
23.07.2020, 14:04
1 ответ

С оболочкой 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 или более(*)0s, за которыми следует один из 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.

3
18.03.2021, 23:18

Теги

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