Замена текста из списка замен. Добавленная сложность: обратные косые черты

Ширина данных = 64 (8 банков * 8 битов)

Общая ширина = 72 (9 банков * 8 битов)

Дополнительный банк указывает, что ECC активен.

4
31.12.2014, 15:41
5 ответов

Необходимо будет выйти из всех символов, которые специальны в regexps, не просто обратных косых чертах, но также и [.*^$ и s разделитель (для sed). В Perl используйте quotemeta функция.

Дальнейшая проблема с Вашей попыткой - это, когда Вы работаете set -- $line, оболочка выполняет свое собственное расширение: это выполняет globbing в дополнение к разделению слова, поэтому если Ваша строка содержит a* b* и существуют названные файлы a1 и a2 в текущем каталоге затем Вы будете заменять a1 с a2. Необходимо выключить globbing с set -f в этом подходе.

Вот решение, которое искажает заменяющий список непосредственно в список sed аргументов. Это предполагает, что нет никакого пробела в исходных текстах и текстах замены, но что-либо кроме пространства и новой строки нужно рассматривать правильно. Первая замена добавляет a \ прежде чем символы, для которых нужны защита и вторая замена, поворачивают каждую строку из foo bar в -e s/foo/bar/g. Предупреждение, непротестированное.

set -f
sed_args=$(<replacement sed -e 's~[/.*[\\^$]~\\&~g' \
                            -e 's~^\([^ ]*\)  *\([^ ]*\).*~-e s/\1/\2/g~')
sed -i $sed_args target

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

perl -i -pe 'BEGIN {
   open R, "<replacement" or die;
   while (<R>) {
       chomp;
       ($from, $to, @ignored) = split / +/;
       $s{$from} = $to;
   }
   close R;
   $regexp = join("|", map {quotemeta} keys %s);
}
s/($regexp)/$s{$1}/ego'
4
27.01.2020, 20:50
  • 1
    Perl работает отлично; спасибо за подсказку о quotemeta. Я все еще немного удивлен, что выполнение дословных строковых замен из списка не имело некоторого простого консервированного решения, но я доволен кодом Perl. –  Leo Alekseyev 17.04.2011, 03:37
  • 2
    Существует незаконченное предложение редактирования о добавлении chomp –  Michael Mrozek♦ 17.04.2011, 08:37
  • 3
    @Michael: Предложенные редактирования оставляют уведомление на каждой странице, таким образом, я прохожу их так или иначе (редкие времена, когда Вы не достигаете их сначала). –  Gilles 'SO- stop being evil' 17.04.2011, 15:01

Это - попытка выйти из обратной косой черты с помощью расширения параметра с заменой шаблона.

$ set -- \\foo \\bar
$ echo $1
\foo
$ echo ${1/\\/\\\\}
\\foo
$ echo "This is \foo to me"
This is \foo to me
$ echo "This is \foo to me" | sed s/${1/\\/\\\\}/${2/\\/\\\\}/
This is \bar to me
$ 
2
27.01.2020, 20:50

Для простых случаев существуют простые решения, поэтому если у Вас, оказывается, есть чистые, простые, базовые слова, без.? + * {} () [] \/и возможно более необычный sed-материал, можно передать список пар к sed-командному-файлу с sed:

sed -re 's,(^\\| \\|$),/,g;s/^/s/;s/$/g/' pairs.txt > pairs.sed
sed -f pairs.sed input > output
2
27.01.2020, 20:50

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

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

0
27.01.2020, 20:50

Это делает то же предположение о пробелах, что и ответ @Gilles, но он вытесняет , в то время как ... Прочитайте LOOP. Это первое обратное слаблю скрещивает любое возникновение любого из SED , затем печатает текущий номер строки, затем глобально заменяет каждую пару символов несмотря на то, что он может найти в работе SED Замечательное заявление. Далее в трубопроводе второй сед преобразует первую SED вывод на что-то вроде:

[linenum]{
s/\1/\2/g;s/\1/\2/g;
}

... поэтому третий SED может прочитать его скрипт на stdin и работать непосредственно на file2 без какого-либо оболочки с петлей оболочки.

<file1 \
sed 's|[]\*/^$.[]|\\&|g;=
     s|\([^ ]*\) \([^ ]*\)|s/\1/\2/g;|g' |
sed 'N;s/\(\n\)\(.*\)/{\1\2\1}\1/'       |
sed -f - file2
0
27.01.2020, 20:50

Теги

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