Используя sed для замены строки содержанием переменной, даже если это - символ ESC

Я использую sed -e "s/\*DIVIDER\*/$DIVIDER/g" заменять *DIVIDER* с указанной пользователями строкой, которая хранится в $DIVIDER. Проблема состоит в том, что я хочу, чтобы они смогли указать символы ESC как свой делитель, как \n или \t. Когда я пробую это, я только заканчиваю с буквой N или t, или и так далее.

У кого-либо есть какие-либо идеи о том, как сделать это? Это будет значительно цениться!

Править: Вот суть сценария, я должен пропускать что-то.

curl --silent "$URL" > tweets.txt

if [[ `cat tweets.txt` == *\<error\>* ]]; then
    grep -E '(error>)' tweets.txt | \
    sed -e 's/<error>//' -e 's/<\/error>//' |
    sed -e 's/<[^>]*>//g' |

head $headarg | sed G | fmt

else
    echo $REPLACE | awk '{gsub(".", "\\\\&");print}'
    grep -E '(description>)' tweets.txt | \
    sed -n '2,$p' | \
    sed -e 's/<description>//' -e 's/<\/description>//' |
    sed -e 's/<[^>]*>//g' |
    sed -e 's/\&amp\;/\&/g' |
    sed -e 's/\&lt\;/\</g' |
    sed -e 's/\&gt\;/\>/g' |
    sed -e 's/\&quot\;/\"/g' |
    sed -e 's/\&....\;/\?/g' |
    sed -e 's/\&.....\;/\?/g' |
    sed -e 's/^  *//g' |
    sed -e :a -e '$!N;s/\n/\*DIVIDER\*/;ta' |   # Replace newlines with *divider*.
    sed -e "s/\*DIVIDER\*/${DIVIDER//\\/\\\\}/g" |          # Replace *DIVIDER* with the actual divider.

    head $headarg | sed G
fi

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

5
задан vilhalmer 13 February 2010 в 16:23
поделиться

5 ответов

Необходимо использовать $ .ajax, если не используется $ .ajaxSetup (), но это не самый разумный выбор.

Почему вы не должны использовать $ .ajax?

-121--1645550-

Имеется 2 варианта: $ .ajax () или $ .ajaxSetup () .

Использование $ .ajax ():

$.ajax({
  type: 'POST',
  url: url,
  data: data,
  success: success
  dataType: dataType
});

Или перед отправкой $ .ajaxSetup (), но это влияет на все запросы ajax:

$.ajaxSetup({
   beforeSend: myFunc,
   complete: myCompleteFunc
});
-121--1645547-

Можно использовать bash, чтобы избежать обратной косой черты:

sed -e "s/\*DIVIDER\*/${DIVIDER//\\/\\\\}/g"

Синтаксис $ {имя/шаблон/строка} . Если образец начинается с /, каждое вхождение образцов в имя заменяется на последовательности . В противном случае заменяется только первое вхождение.

7
ответ дан 14 December 2019 в 01:07
поделиться

Необходимо использовать $ .ajax, если не используется $ .ajaxSetup (), но это не самый разумный выбор.

Почему вы не должны использовать $ .ajax?

-121--1645550-

Имеется 2 варианта: $ .ajax () или $ .ajaxSetup () .

Использование $ .ajax ():

$.ajax({
  type: 'POST',
  url: url,
  data: data,
  success: success
  dataType: dataType
});

Или перед публикацией выполните $ .ajaxSetup (), но это влияет на все запросы ajax:

$.ajaxSetup({
   beforeSend: myFunc,
   complete: myCompleteFunc
});
-121--1645547-

Вам просто нужно избежать escape char.

\n будет соответствовать\n

\будет соответствовать\

\\будет соответствовать\

0
ответ дан 14 December 2019 в 01:07
поделиться

Возможно:

case "$DIVIDER" in
(*\\*) DIVIDER=$(echo "$DIVIDER" | sed 's/\\/\\\\/g');;
esac

Я играл с этим скриптом:

for DIVIDER in 'xx\n' 'xxx\\ddd' "xxx"
do
    echo "In:  <<$DIVIDER>>"
    case "$DIVIDER" in     (*\\*) DIVIDER=$(echo "$DIVIDER" | sed 's/\\/\\\\/g');;
    esac
    echo "Out: <<$DIVIDER>>"
done

Запускать с 'ksh' или 'bash' (но не 'sh') на MacOS X:

In:  <<xx\n>>
Out: <<xx\\n>>
In:  <<xxx\\ddd>>
Out: <<xxx\\\\ddd>>
In:  <<xxx>>
Out: <<xxx>>
1
ответ дан 14 December 2019 в 01:07
поделиться

Кажется, что это простая замена:

$ d='\n'
$ echo "a*DIVIDER*b" | sed "s/\*DIVIDER\*/$d/"
a
b

Возможно, я не понимаю, чего вы пытаетесь добиться.

Тогда, возможно, этот шаг мог бы занять место двух последних ваших:

sed -n ":a;$ {s/\n/$DIVIDER/g;p;b};N;ba"

Обратите внимание на пробел после знака доллара. Он не позволяет оболочке интерпретировать "${s..." как имя переменной.

И как предположил ghostdog74, у вас слишком много обращений к sed. Возможно, вы сможете заменить многие символы труб на обратные слеши (продолжение строки) и удалить "sed" из всех, кроме первого (оставить "-e" везде). (не проверено)

1
ответ дан 14 December 2019 в 01:07
поделиться

Используя FreeBSD sed (например, в Mac OS X), вы должны предварительно обработать пользовательский ввод $ DIVIDER:

d='\n'
d='\t'
NL=$'\\\n'
TAB=$'\\\t'
d="${d/\\n/${NL}}"
d="${d/\\t/${TAB}}"
echo "a*DIVIDER*b" | sed -E -e "s/\*DIVIDER\*/${d}/"
0
ответ дан 14 December 2019 в 01:07
поделиться
Другие вопросы по тегам:

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