Grep ведет себя по-другому на Трэвисе по сравнению с местным - PullRequest
0 голосов
/ 04 января 2019

Я унаследовал скрипт сборки, который проверяет заявления об авторском праве в нашей сборке Travis, получая список файлов, которые были изменены, и следя за тем, чтобы в них было заявление об авторском праве с указанием текущего года.Часть сценария, которая извлекает годы, использует grep для извлечения лет следующим образом:

GOSRCFILES=($(git diff --name-only origin/master | grep -v vendor | grep '\.go$'))
for GOFILE in "${GOSRCFILES[@]}"; do
  if grep -q "(C) Copyright" $GOFILE; then
      YEAR_LINE=$(grep -m 1 "(C) Copyright" $GOFILE)
      echo "Year line in ${GOFILE} is '${YEAR_LINE}'"
      YEARS=($(echo $YEAR_LINE | grep -oE '\d{4}'))
      echo "Years is ${YEARS[@]}"
  fi
done

Это работает нормально локально (на Mac), но когда он запускается на Travis, он терпит неудачу.Локальный вывод:

Year line in main.go is ' * (C) Copyright IBM Corp. 2017, 2018 All Rights Reserved.'
Years is 2017 2018

В то время как на Travis он печатает:

Year line in main.go is ' * (C) Copyright IBM Corp. 2017, 2018 All Rights Reserved.'
Years is 

Как вы можете видеть, он находит строку авторского права в порядке, но команда, которая извлекает YEARS (YEARS=($(echo $YEAR_LINE | grep -oE '\d{4}'))) от этого не получается.Я прочитал справочную страницу для grep и не могу понять, почему она будет вести себя иначе для этой команды.

1 Ответ

0 голосов
/ 04 января 2019

escape \d - это расширение Perl, которое обычно не поддерживается в grep без дополнительных опций.Вместо этого используйте [0-9] или класс POSIX [[:digit:]].(Поймите тонкие различия; POSIX зависит от локали, но в Travis локаль, вероятно, является чем-то недопустимым.)

Тангенциально, если вы используете массив только один раз, не используйте массив;и вы можете избежать выполнения первого grep дважды;и не используйте заглавные буквы для ваших личных переменных;и процитируйте свои переменные;и распечатайте диагностику со стандартной ошибкой.

for gofile in $(git diff --name-only origin/master | grep -v vendor | grep '\.go$'); do
  if year_line=$(grep -m 1 "(C) Copyright" "$gofile"); then
    echo "Year line in $gofile is '$year_line'" >&2
    years=($(echo "$year_line" | grep -oE '[[:digit:]]{4}'))
    echo "Years is ${years[@]}" >&2
  fi
done
...