Ошибка неправильной замены SED - PullRequest
1 голос
/ 23 августа 2011

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

find * | sed -e '/\(.*\..*\)/ !d' | sed -e "s/^.*/\${File} \${INST\_FILES} &/" | sed -e "s/\( \)\([a-zA-Z0-9]*\/\)/\/\2/" | sed -e "s/\(\/\)\([a-zA-Z0-9\_\-\(\)\{\}\$]*\.[a-zA-Z0-9]*\)/ \2/"

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

#!/bin/bash
nsisscript=myscript.sh
FILES=*
for f in $(find $FILES); do 
v=`echo $f | sed -e '/\(.*\..*\)/ !d' | sed -e "s/^.*/\${File} \${INST\_FILES} &/" | sed -e "s/\( \)\([a-zA-Z0-9]*\/\)/\/\2/" | sed -e "s/\(\/\)\([a-zA-Z0-9\_\-\(\)\{\}\$]*\.[a-zA-Z0-9]*\)/ \2/"`
sed -i.backup -e "s/\;Insert files here/$v\\n&/" $nsisscript 
done 

Не могли бы вы помочь мне понять, в чем разница между этими двумя случаями и почему я получаю эту ошибку?

Заранее спасибо!

Ответы [ 2 ]

0 голосов
/ 23 августа 2011

Анализ внутри подстановки команд в стиле backquote немного странный - он требует дополнительного уровня экранирования (то есть обратной косой черты), чтобы контролировать, когда происходит расширение.Уродливое решение: добавьте больше обратной косой черты.Лучшее решение: используйте $() вместо обратных кавычек - он делает то же самое, но без странных проблем с синтаксическим анализом и экранированием.

Кстати, ваш скрипт, похоже, имеет некоторые другие проблемы.Во-первых, я не знаю о sed в вашей системе, но версии, с которыми я знаком, интерпретируют \n в подстановке не как новую строку (которую, я полагаю, вы хотите), а как литерал n символ.Одним из решений является включение в подстановку буквального символа новой строки (которому предшествует обратная косая черта).

Кроме того, цикл выполняется для каждого найденного файла, но для файлов, которые не имеют точки в имени, первыйКоманда sed удаляет их, $v пуста, и вы добавляете пустую строку в myscript.sh.Вы должны либо поместить фильтрующий вызов sed в оператор for, либо добавить его в качестве фильтра в команду find.

#!/bin/bash
nsisscript=myscript.sh
nl=$'\n'
FILES=*
for f in $(find $FILES -name "*.*"); do 
    v=$(echo $f | sed -e "s/^.*/\${File} \${INST\_FILES} &/" | sed -e "s/\( \)\([a-zA-Z0-9]*\/\)/\/\2/" | sed -e "s/\(\/\)\([a-zA-Z0-9\_\-\(\)\{\}\$]*\.[a-zA-Z0-9]*\)/ \2/")
    sed -i.backup -e "s/\;Insert files here/$v\\$nl&/" $nsisscript 
done
0 голосов
/ 23 августа 2011

Что ж, я думаю, что ваше экранирование в INST_FILES странное, так как подчеркивание не является специальным символом в shell или в sed. Ошибка исчезнет, ​​если вы удалите «\» перед «_»

мои 2 цента

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...