2015-05-21 3 views
0

Я новичок в UNIX сценариев, и я пытаюсь использовать SED команды, чтобы заменить текст, но я получаю эту ошибку:Почему я получаю этот неизвестный вариант ошибки

sed: -e expression #1, char 51: unknown option to `s'

Вот фрагмент кода что у меня есть:

sed -e "/^#PBS -o ${rundir}/posttest/s#_CMODEL#${cmodel}#" \ 
     -e "/^#PBS -e ${rundir}/posttest/s#_CMODEL#${cmodel}#" \ 
    ${rundir}/run_post.shell >${rundir}/run_post.${cmodel}.sh 

Пожалуйста, дайте мне знать, что я делаю неправильно. Большое спасибо!!!

+0

У '$ {rundir}' есть '/' символы в нем? – Barmar

+2

Если вы ожидаете, что '/^# PBS -o $ {rundir}/posttest /' будет шаблоном регулярного выражения, который указывает, к каким строкам применяется команда 's', тогда вам нужно избежать внутреннего'/'. В противном случае будет полезно объяснение того, что вы пытаетесь сделать. – rici

+0

@Barmar yes $ {rundir} имеет/в нем что-то меняет что-то – user3431573

ответ

0

Проблема заключается в том, что регулярное выражение используется в качестве адреса завершается первый /, которые могли бы быть в ${rundir} или может быть / сразу же после этого; это, конечно, не / после posttest.

В общем, интерполяция переменных в регулярное выражение несколько опасна. Если содержимое переменной содержит метасимволы регулярных выражений, то, скорее всего, это может произойти непредвиденным образом. Если, как и в данном случае, значение переменной может включать терминатор регулярного выражения, то часть значения переменной будет интерпретирована как команда.

С учетом этого предупреждения у вас есть несколько вариантов. Если вы знаете, что какой-то символ, скажем :, не отображается в ${rundir}, то вы можете использовать этот символ в качестве терминатора регулярных выражений. (Обратите внимание на обратную косую черту, которая, как вы говорите СЕПГ, что далее следует регулярное выражение.)

sed -e "\:^#PBS -o ${rundir}/posttest:s#_CMODEL#${cmodel}#" \ 
    -e "\:^#PBS -e ${rundir}/posttest:s#_CMODEL#${cmodel}#" \ 
    "${rundir}/run_post.shell" >"${rundir}/run_post.${cmodel}.sh" 

В качестве альтернативы, вы можете обратной косой черты избежать буквального / и использовать синтаксис шаблонов подстановки Баш на обратной косой черты избежать всех / в $rundir:

${rundir//\//\\/} 

(Как уже упоминалось выше, вы действительно должны бежать все возможные метасимволов, включая обратную косую черту себя.)

+0

Большое вам спасибо !!! – user3431573

0

Вам необходимо избежать косой черты в регулярном выражении, которое используется в качестве адреса. В противном случае первая косая черта закончит регулярное выражение, а следующий символ будет принят как команда sed для работы с этими выделенными линиями. Вам нужно сделать это как для косых черт в $rundir, так и для косой черты, которая у вас есть между ${rundir} и posttest.

Для переменной вы можете избежать косых черт, используя синтаксис ${parameter/pattern/replacement} bash, описанный here.

sed -e "/^#PBS -o ${rundir//\//\\/}\/posttest/s#_CMODEL#${cmodel}#" \ 
     -e "/^#PBS -e ${rundir//\//\\/}\/s#_CMODEL#${cmodel}#" \ 
    ${rundir}/run_post.shell >${rundir}/run_post.${cmodel}.sh 
Смежные вопросы