Используйте printf
со строкой формата, которая определяет ширину поля и заполнение нулями для целых чисел, например
printf -v newname 'S%02dE%02d%s' "$((10#${BASH_REMATCH[2]}))" "$((10#${BASH_REMATCH[3]}))" "${BASH_REMATCH[4]}"
Обратите внимание на использование $ ((10 # $ {BASH_REMATCH [n]}))
для принудительного вычисления десятичной дроби в таких случаях, как 09
Тестирование (я немного изменил ваше регулярное выражение BTW ):
reg='^([^0-9]*)([0-9][0-9]*)[^0-9]*([0-9][0-9]*)(\....)$'
for filename in *.mp4; do
if [[ $filename =~ $reg ]]; then
printf -v newname 'S%02dE%02d%s' "$((10#${BASH_REMATCH[2]}))" "$((10#${BASH_REMATCH[3]}))" "${BASH_REMATCH[4]}"
echo mv "$filename" "$newname"
fi
done
mv Some Series01.Episode02.mp4 S01E02.mp4
mv SomeSeries1Episode03.mp4 S01E03.mp4
mv Some_Series.1_Episode.1.mp4 S01E01.mp4
Возможно, более надежным было бы использовать регулярное выражение только для сопоставления первых двух последовательностей цифр и использовать подстановку параметров оболочки для обработки расширения:
reg='([0-9][0-9]*)[^0-9]*([0-9][0-9]*)'
for filename in *.mp4 *.mkv; do
name="${filename%.*}"
ext="${filename##*.}"
if [[ $name =~ $reg ]]; then
printf -v newname 'S%02dE%02d.%s' "$((10#${BASH_REMATCH[1]}))" "$((10#${BASH_REMATCH[2]}))" "${ext}"
echo mv "$filename" "$newname"
fi
done
mv Some Series01.Episode02.mp4 S01E02.mp4
mv SomeSeries09Episode10.mp4 S09E10.mp4
mv SomeSeries1Episode03.mp4 S01E03.mp4
mv Some_Series.1_Episode.1.mp4 S01E01.mp4
mv Breaking.Bad.S01E01.576p.BluRay.DD5.1.x264-HiSD.mkv S01E01.mkv
В качестве альтернативы, если в вашей системе есть на основе perl переименовать
/ prename
команду, вы могли бы что-то вроде
prename -vn -- 's/.*(\d+).*(\d+)/sprintf "S%02dE%02d.mp4", $1, $2/e' *.mp4
Постройте шаблон из списков слов. Из file1.txt
, содержащего, например, one
, un
, eins
и file2. txt
, содержащий two
, deux
, zwei
, необходимо получить регулярное выражение (в синтаксисе ERE)
(one|un|eins).*(two|deux|zwei)
Если списки слов не содержат специальных символов в regex, то достаточно заменить новые строки на |
(оператор "или"), кроме последней.
words1=$(tr '\n' '|' <file1.txt); words1=${words1%\|}
words2=$(tr '\n' '|' <file2.txt); words2=${words2%\|}
grep -E "($words1).*($words2)"
Если списки слов могут содержать специальные символы, то их нужно заключить в кавычки.
words1=$(<file1.txt tr '\n' '|' | sed 's/[][\\().*?+|]/\\&/g'); words1=${words1%\|}
words2=$(<file2.txt tr '\n' '|' | sed 's/[][\\().*?+|]/\\&/g'); words2=${words2%\|}
grep -E "($words1).*($words2)"
Обратите внимание, что если вам не важен порядок слов и вы можете принять перекрывающиеся совпадения (например, принять twone
как содержащий и one
и two
), то все, что вам нужно, это два вызова grep:
grep -f file1.txt | grep -f file2.txt
Сначала вам нужно экранировать специальные символы в этих двух файлах (если есть), а затем присоединить их, например, вставьте
, чтобы получить список шаблонов, которые вы затем использовали бы через grep
-f
... и если у вас не слишком много файлов, которые вы не используете Цикл не нужен, поскольку grep
принимает несколько аргументов:
paste -d'.*' <(sed 's/[.[\*^$]/\\&/g' file1.txt) /dev/null \
<(sed 's/[.[\*^$]/\\&/g' file2.txt) | grep -f - /root/listoffiles/*php >> found.txt