Как мне извлечь число из имени файла, стоящего перед данной строкой?

Да, вы все делаете правильно. Написанный вами цикл будет выполнять команды в точном порядке, в котором вы их перечислили, хотя важно отметить, что ошибка в одной команде не приведет к завершению цикла, она продолжится со следующей командой, фактически игнорируя ошибку.

0
31.03.2018, 16:12
4 ответа

Оператор условного тестирования Bash [[может сравнивать имена файлов с регулярным выражением и извлекать выражения в скобках:

shopt -s nocaseglob
for f in *booklets*
do
  [[ $f =~ ([[:digit:]]+)[^[:digit:]]?booklets ]] && echo "${BASH_REMATCH[1]}"
done

Это зациклится на каждом файле, который содержит (регистрозависимое -нечувствительное )слово "буклеты" в текущем каталоге. Если вы хотите, чтобы что-то выполнялось одновременно с одним файлом, вы можете упростить описанное выше и поместить это в скрипт или функцию :

.
extractnumber ()
(
    shopt -s nocaseglob
    if [ ! -f "$1" ]; then echo "File $1 not found!"; return 1; fi
    [[ $1 =~ ([[:digit:]]+)[^[:digit:]]?booklets ]] && echo "${BASH_REMATCH[1]}";
)

... и затем назовите его:

$ extractnumber 35BOOKLETS.pdf
35
$ extractnumber MATH232\ Exam\ 01\ 99\ booklets.pdf
99
$ extractnumber 101s18-exam02--100-booklets.pdf
100
$ extractnumber foobar
File foobar not found!
2
28.01.2020, 02:14

Я сделал это, как указано ниже pythonscript.py, и направил вывод для поиска необходимых совпадений. Я мог бы использовать только python, но я хотел использовать grep, поэтому конвейеризовал вывод

Входной файл с именем inputfileфайл:

101s18-exam02--100-booklets.pdf
MATH232 Exam 01 99 booklets.pdf
35BOOKLETS.pdf

Использование:

python pythonscript.py |grep -o "^[0-9]*"

pythonscript.pyсодержит:

#!/usr/bin/python
import re
o = open('inputfile','r')
k=re.compile(r'\d{2,3}\s?-?booklets',re.IGNORECASE)
for g in o:
    u=re.search(k,g)
    if u:
       print u.group()

Выход:

100
99
35
1
28.01.2020, 02:14

Использование реализации grep, которая знает флаг -oиtr:

#!/bin/sh

printf '%s\n' "$@" | grep -oiE '[0-9]+[^0-9]*booklets' | tr -dc '0-9\n'

Это shскрипт (, а не bash, хотя он будет работать и с bash). Он предполагает, что ни одна строка, переданная ему в командной строке, не содержит встроенного в нее символа новой строки.

Расширенное регулярное выражение [0-9]+[^0-9]*bookletsбудет соответствовать любой строке, похожей на <integer><zero or more non-digit characters><"booklets">, а с -oэто именно то, что будет возвращено из grep. trпросто удаляет из вывода grepвсе, что не является цифрой или новой строкой.

trможно заменить на sed 's/[^0-9].*//', что удалит все, начиная с первого нецифрового символа -в строке.

Проверка:

$ sh script.sh 101s18-exam02--100-booklets.pdf
100
$ sh script.sh "MATH232 Exam 01 99 booklets.pdf"
99
$ sh script.sh 35BOOKLETS.pdf
35

$ sh script.sh 101s18-exam02--100-booklets.pdf "MATH232 Exam 01 99 booklets.pdf" 35BOOKLETS.pdf
100
99
35

Обратите внимание, что строки с пробелами необходимо заключать в кавычки.

3
28.01.2020, 02:14

Вы можете попробовать этот sed

sed -E '
  s/^/ /
  s/.*[^0-9]([0-9]+).?[bB][oO]{2}[kK][lL][eE][tT][sS].*/\1/
' infile
1
28.01.2020, 02:14

Теги

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