Удалить символ между двумя известными строками

У меня есть набор данных, как показано ниже:

\"XXX \ START sapiodj \\" aj \d 2387 END hddo\" START bbcc \\" END ss 

Мои требования: я хочу удалить все вхождения обратной косой черты и двойные кавычки между START и END.

Желаемый результат:

 \"XXX \ START sapiodj aj d 2387 END hddo\" START bbcc END ss 

Заметка:

  1. Несколько START / END в одной строке
  2. Я хочу удалить \ и " только между START и END и нигде больше
  3. И мой файл имеет несколько строк (строки, похожие на то, что показано выше)
  4. Мне нужно использовать только sed

Я попробовал что-то вроде ниже (сначала пытался избавиться от " одного»), и это не дало мне желаемого результата:

 sed '/START/,/END/ s/"//g' 

4 Solutions collect form web for “Удалить символ между двумя известными строками”

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

 sed -e 's/END/`/g;:X' -e 's/\(START[^`]*\)["\]/\1/g;tX' -e 's/`/END/g' 

На самом деле это не так сложно. Вы всегда можете разграничить раздел с помощью \n ewline или вы можете разложить разделитель на \n ewline временно. И вы можете сделать это без цикла:

 sed 's/$/START/;s/END/& /g; y/D\n/\nD/ s/\([^D]*START\)*[D\"]*/\1/g y/\n/D/;s/.....$// ' <<\IN \"XXX \ START sapiodj \\" aj \d 2387 END hddo\" START bbcc \\" END ss IN 

Иногда вам просто нужно немного подумать о проблеме. Вместо того, чтобы удалить все « \\" между START и END если мы вместо этого перейдем к проблеме, как мы можем сохранить \\" только если они происходят между главой строки и START , START и END , а последний END и хвост линии становится немного легче (если, по общему признанию, не интуитивно так) . Это связано с тем, как sed обрабатывает * совпадения s/// нулем или больше в контексте g lobal s/// ubstitution .

В то время как бит START -1- START будет вымываться как естественный результат остальной части этого, последний бит END -to-tail не будет – и поэтому нам нужно добавить еще один START в конец строки , После получения нашего дополнительного START мы добавим символ \n ewline к каждому появлению END . И затем с помощью команды y/// транслитерации мы одновременно продаем все D символы для \n ewlines и наоборот. Кстати, команда y/// транслитерации не только очень удобна здесь, но и более эффективна, чем s/// ubstitution.

На этом этапе в нашем пространстве шаблонов будет напечатан:

 \\"XXX \\ START sapiodj \\\\" aj \\d 2387 EN\nD hddo\\" START bbcc \\\\" EN\nD ssSTART$ 

Как вы можете видеть, теперь все \\" символы, требующие сохранения, лежат прямо между головой строки или строками D и START и между ними нет D s. Таким образом, g lobal s/// ubstitution, который удаляет нежелательные символы – для включения наших дополнительных D s – также заменяют те, которые требуют экономии с собой. Последнее нам нужно только для замены \n и D s и удаления последнего START .

Таким образом, вы можете надежно делиться полями с sed независимо от ввода, и вам не нужно полагаться на любого несуществующего персонажа, но тот, который гарантированно никогда не будет происходить на линии, – и это, конечно, символ \n .

Когда он закончит печать, выполните следующие действия:

 \"XXX \ START sapiodj aj d 2387 END hddo\" START bbcc END ss 

С sed :

 sed 's/:/::/g;s/</:l/g;s/>/:g/g; # escape :, <, > s/START/&</g; s/END/>&/g; # replace START/END with <> :1 s/\(<[^>]*\)[\"]/\1/g;t1 s/[<>]//g;s/:g/>/g;s/:l/</g;s/::/:/g; # restore <>:' 

С perl :

 perl -pe's|START.*?END|$&=~y/\\"//rd|ge' 

Вы указали в комментарии, что awk также разрешен. Поэтому я основываю свой ответ на этом.

Предполагая, что ваши START и END сбалансированы, если вы разделите строку на любом слове, вы обнаружите, что хотите удалить обратную косую черту и двойные кавычки из всех четных полей. К этому концу:

 awk -F 'START|END' '{ for(i=2;i<=NF;i+=2){ # For each even-numbered field gsub(/["\\]/,"",$i) # Remove " and \ from it $i="START"$i"END" # Put START and END back around it } }' your_file 

Это предполагает, что ваша реализация awk имеет функцию gsub которую я не могу ручаться.

В качестве побочного примечания ваш sed не работает, потому что он в основном говорит «применить подстановку к диапазону строк, который начинается с строки, соответствующей START и заканчивается линией, соответствующей END ».

  • Заменяйте каждую вкладку ТОЛЬКО в начале каждой строки пробелами
  • Удалите 2 и 3 строки в текстовом файле, но не 1
  • Подсчет определенного последовательного символа с его местоположением и длиной
  • Техника для объединения групп последовательных линий, разделенных по шаблону
  • чтение из файла и изменение его шаблона в массив?
  • строки в столбцы с awk
  • Удалить последнюю запятую в шаблоне
  • Отображать слова в цвете
  • sed - удаление нуля - / 08 / to / 8 /
  • Как извлечь строки между одинаковыми шаблонами из файла
  • удалять только определенные текстовые вхождения из строки с помощью sed
  • Передача разобранного вывода sed для поиска (в этом направлении)
  • Linux и Unix - лучшая ОС в мире.