Негативный взгляд с awk или sed невозможен, но поддерживается только perl - PullRequest
2 голосов
/ 18 апреля 2019

У меня есть текст, который занимает несколько строк

    ... someabove text

  jpqpq====== mcvnmcv

    .... s;ql[[pw]]

    <<<<<< uyuuey

    ... middle text

  jhasjh  ======dsadsas

    .... grqywtrt

  klklk  <<<<<<alallal

    ... someend text

Я хочу удалить весь текст из ====== till <<<<<<

В sublime text я использую

найти:(?s)(======(?:(?!======).)*?<<<<<<)

replace:

и все вхождения удалены, а выходные данные выглядят

    ... someabove text

  jpqpq     uyuuey

    ... middle text

  jhasjh  alallal

    ... someend text

Теперь я хочу сделать это с помощью командной строки, используя sed or awk or anything.Потому что каждый раз открывать файл и заменять его утомительно

Но я искал sed и awk, я обнаружил, что они не поддерживают регулярные выражения, отличные от нуля.и в этих случаях используется perl

Может ли кто-нибудь подтвердить, что sed и awk не могут использовать такие шаблоны, как этот (======(?:(?!======).)*?<<<<<<), и должны попробовать некоторые косвенные способы.

Тем не менее я ищу, каксделать это с помощью sed и awk (даже косвенно), а также perl (если разрешен просмотр)

с perl также не сработало

perl -ne 's/"(======(?:(?!======).)*?<<<<<<)"/""/g; print' file

пустой вывод

Ответы [ 3 ]

2 голосов
/ 18 апреля 2019

Да, ни awk, ни sed не поддерживают обходные пути.Более конкретно, используемые ими регулярные выражения не поддерживают их.

Ваша команда perl не выполнена, потому что вы должны сказать ей, что это модификатор многострочной строки (s).Но это все равно не получится, потому что perl читает входные данные построчно и применяет оператор замены к каждой строке.Если вы хотите, чтобы он совпадал по всему файлу, вам нужно добавить к нему -0777.Это делает то, что вам нужно:

$ perl -0777pe 's/======.*?<<<<<<//gs' file 
    ... someabove text

  jpqpq uyuuey

    ... middle text

  jhasjh  alallal

    ... someend text

-0777 заставляет Perl изматывать весь файл.-p заставляет печатать каждую строку, а -e дает то, что вы хотите.Я также упростил ваше регулярное выражение, так как нет причин использовать такой сложный подход.======.*?<<<<<< будет соответствовать ======, тогда .*?<<<<<< означает "как можно меньше символов до <<<<<<. Наконец, /sg в конце активирует многострочные строки (s, что позволяет .для соответствия символам новой строки) и заставит оператора замены работать глобально (g), поэтому он заменит все вхождения.


В sed, если ваши маркеры были в строках сами по себе, то есть еслиВы хотели удалить все в строках ====== и <<<<<<, вы можете сделать это:

$ sed '/======/,/<<<<<</d' file 
    ... someabove text


    ... middle text


    ... someend text

Но это не подойдет вам здесь.

0 голосов
/ 23 апреля 2019

если нет символа < в пределах ===== до <<<<< в файле данных 'd', пробовал на gnu sed </p>

sed -Ez 's/={6}[^<]*<{6}//g' d
0 голосов
/ 18 апреля 2019

Правильно, вы не получите looka - что угодно с sed или awk, но вам это тоже не нужно, это просто синтаксический сахар.С GNU awk для нескольких символов RS:

$ awk -v RS='<<<<<<' -v ORS= 'RT{sub(/======.*/,"")} 1' file
    ... someabove text

  jpqpq uyuuey

    ... middle text

  jhasjh  alallal

    ... someend text

и с GNU sed для -z:

$ sed -z 's/@/@A/g; s/{/@B/g; s/}/@C/g; s/======/{/g; s/<<<<<</}/g;
          s/{[^{}]*}//g;
          s/}/<<<<<</g; s/======/{/g; s/@C/}/g; s/@B/{/g; s/@A/@/g
' file
    ... someabove text

  jpqpq uyuuey

    ... middle text

  jhasjh  alallal

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