Извлечение просто единственной группы от регулярного выражения

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

head удаляет запаздывание символа конца строки, вставленного ImageMagick.

Сценарий содержит команду простофили, которая устанавливает выходного разделителя полей на маловероятный символ, вычисляет различие в квадрате и печатает назад пару difference|file имя. Вид выполняется, и ненужная информация (различие в соотношении сторон в квадрате) отобрана cut.

#!/bin/sh
if [ x"$1" = "x" ] ; then
  echo "Usage: $0 TargetAspectRatio" >&2
  exit 2
fi
ASPECT_CMD="BEGIN{OFS=\"|\";}\
{\
print (\$1-$1)^2, \$2;\
}"
identify -format "%[fx:w/h]:%M\n" *.jpg | head -n-1 | gawk -F":" "$ASPECT_CMD" | sort -k1 -t"|" | cut -f2 -d"|"
3
27.11.2013, 02:36
2 ответа

Если Ваш grep GNU grep и принятие числа Вы ищете, единственное число на строке:

zgrep -ioEe '[0-9]+(\.[0-9]+)?' *

В противном случае можно всегда фильтровать zgrepвывод:

zgrep -ie 'total time: .* ms' * | sed 's/.*total time: \(.*\) ms.*/\1/'
4
27.01.2020, 21:20
  • 1
    @Jeremy, Довольный, я мог помочь. См. обновленный ответ, я улучшился sed таким образом, это более точно. Я не знаю то, что прибыло через меня ранее... –  Joseph R. 27.11.2013, 03:06

С GNU grep, можно сочетать две функции для получения то, что Вы хотите:

  • -o опция распечатать только часть соответствия строки;
  • Регулярные выражения Perl и их нулевая ширина lookaround утверждения для ограничения, что может появиться прежде и после соответствия.
zgrep -Pi -o '(?<=total time: )([0-9.]+)(?= *ms)' *

С другой стороны, Вы могли бы назвать Perl.

perl -MPerlIO::gzip -e 'for (@ARGV) {
    open IN, (/\.gz$/ ? "<:gzip" : "<"), $_ or die "$_: $!";
    $name = $_;
    while (<IN>) {
        if (/total time: ([0-9.]+) *ms/i) {print "$name:$1\n"}
    }
    close IN
}' *

Без этих инструментов можно выполнить итерации по файлам вручную и вызову sed снимать изоляцию со всего, но чем Вы интересуетесь.

for x in *; do
  case "$x" in
    *.gz) <"$x" gunzip;;
    *) cat "$x";;
  esac | sed -n -e 's/^.*total time: \([0-9.]*\) *ms.*$/\1/p'
done
0
27.01.2020, 21:20

Теги

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