Разница в синтаксисе Sed для macOS и GNU

#bash #unix #sed #sh

#bash #unix #sed #sh

Вопрос:

У меня есть следующий фрагмент кода, который отлично работает на macOS, но не работает на GNU (я использую MinGW):

 filename=$1
iter_count=$((${#src_op_lst[@]} -1))
for i in $(eval echo "{0..$iter_count}");do
    echo "Checking File :" $filename
    sed -i "" "s/[[:<:]]"${src_op_lst[$i]}"[[:>:]]/"${tgt_op_lst[$i]}"/g" $filename
done
  

Я предполагаю, что причина в том, что sed синтаксис отличается, но я понятия не имею, как заставить его работать на GNU. Я пытался использовать sed -i -e ... , но sed выдает мне следующую ошибку: -e expression #1, char 50: Invalid character class name .

Я очень новичок в написании сценариев bash, извините, если этот вопрос глупый. Любая помощь будет с благодарностью!

Комментарии:

1. [[:<:]] / [[:>:]] являются проблемными токенами. Что вы пытались здесь сделать? Они анализируются как именованный символьный класс, как, например [[:alnum:]] , класс буквенно-цифровых символов

2. [[:<:]] действительно недопустимое имя класса char. Что вы пытаетесь сделать it ?

3. @Aaron @vgersh99 Этот скрипт заменяет все значения из src_op_lst найденных в filename соответствующими значениями в tgt_op_lst

4. Похоже, мое предположение было правильным: unix.stackexchange.com/a/393968/139867 . Я опубликую ответ

5. О, и если вы этого не знаете, ShellCheck — отличный инструмент, который поможет вам точно определить проблемы и плохие методы в сценариях.

Ответ №1:

[[:<:]] и [[:>:]] — это токены, которые macOS sed интерпретирует как направленные границы слов: первый позволяет вам проверить, что вы соответствуете в начале слова, а второй — в конце слова.
Они позволяют вам убедиться, что вы заменяете целые слова, а не части слов (например, избегая перехода professor на confessor , когда вы пытаетесь заменить pro на con ).

Точным эквивалентом в GNU sed будет < и > .

Однако, как человек, знакомый с регулярными выражениями, но не обязательно с множеством различных реализаций, я бы посоветовал вам использовать более распространенное b вместо обоих < и > .
Это граница слова без указания направления, которая будет совпадать, если вы находитесь либо в начале, либо в конце слова. В вашем случае (и в большинстве случаев) это приведет к точно такому же результату, и будущие разработчики, скорее всего, будут знакомы с ним и не пройдут через борьбу, которую вы только что испытали.

Комментарии:

1. Спасибо за помощь, это решение работает для меня!