Да, вы все делаете правильно. Написанный вами цикл будет выполнять команды в точном порядке, в котором вы их перечислили, хотя важно отметить, что ошибка в одной команде не приведет к завершению цикла, она продолжится со следующей командой, фактически игнорируя ошибку.
Оператор условного тестирования 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!
Я сделал это, как указано ниже 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
Использование реализации 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
Обратите внимание, что строки с пробелами необходимо заключать в кавычки.
Вы можете попробовать этот sed
sed -E '
s/^/ /
s/.*[^0-9]([0-9]+).?[bB][oO]{2}[kK][lL][eE][tT][sS].*/\1/
' infile