Замените самое короткое соответствие строкового шаблона

hunzip инструмент распаковки. Для сжатия Вы хотите посмотреть на hzip. Оба будут воздействовать на текстовые файлы, но они оптимизированы для работы с отсортированными словарями и списками слов.

2
19.09.2012, 03:29
2 ответа

По умолчанию sedмеханизм regex является жадным. Это означает, что шаблон всегда соответствует самому долгому соответствию. Необходимо сделать нежадный поиск, но я думаю, что sed не поддерживает нежадные поиски. Поэтому необходимо добавить точку (точки) опоры к шаблону поиска так, чтобы sed находит самое короткое соответствие.

Следующая строка пытается эмулировать нежадное соответствие для Вашего особого случая, и это не требует универсальность, начиная с сингла w между update и первое where делает шаблон недопустимым:

sed -e 's/^Update[^w]*where//ig'\
    -e "s/^/insert into mytemp select * from mytable where  /g" n.txt

Другие regex-механизмы поддерживают эту функцию, как, например, та perl и awk.

Но в Вашем случае я думаю выражение как это

sed -e 's/^Update.\+where\(.\+where.*\)$/\
insert into mytemp select * from mytable where \1/ig'  n.txt

был бы более удобен связанный с Вашей определенной проблемой.

(запаздывание \ в строках выше только добавляются для создания строк более четкими.)

3
27.01.2020, 22:07
  • 1
    Большое спасибо это разрешает эту определенную проблему. Но если у меня есть несколько немного отличающаяся строка как ниже, затем это не делает работ: обновите mytable набор mycol=myvalue где mycol=yourvalue; и вставьте в выбор mytemp * от mytable где mycol=youvalue; –  Nirmal Arri 19.09.2012, 12:16

Регулярное выражение, соответствующее, выполняется слева направо, и с самым долгим соответствием, взятым в предпочтении. Следовательно ^Update.*where соответствует последнему вхождению where на строке.

Один способ сделать это соответствие состоял бы в том, чтобы использовать нежадный квантор для *. Sed не поддерживает нежадные кванторы, но жемчуг делает.

perl -pe 's/^update.*?where//i; s/^/insert into mytemp select .*? from mytable where /'

Иначе то, которое может или не может соответствовать Вашим данным, должно было бы отклонить круглые скобки в имени таблицы и colum настройках.

sed -e 's/^update[^()]*where//i' -e 's/^/insert into mytemp select [^()]* from mytable where /'

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

sed -e 's/ where /\n/' \
    -e 's/^update.*$//i' -e 's/^/insert into mytemp select .* from mytable where /' \
    -e 's/\n/ where/'
0
27.01.2020, 22:07
  • 1
    Gilles, решение для жемчуга работает просто великолепно, большое спасибо! –  Nirmal Arri 19.09.2012, 12:22
  • 2
    Gilles Здорово устранил всю мою боль!Спасибо! –  Nirmal Arri 20.09.2012, 22:34
  • 3
    Хм на самом деле это не работает... Я думал, что это сделало. –  Nirmal Arri 04.10.2012, 22:04
  • 4
    Здесь это, что это делает: у Меня есть несколько updates:UPDATE abciii.cash_activity, УСТАНАВЛИВАЕТ UPDATE_DATE = sysdate, USER_CHAR1 = TO_CHAR (SYSDATE, 'AM MM/DD/YYYY HH:MI:SS'), USER_CHAR2 = 'UXXXXXX' ГДЕ CASH_INT = 41166153 И ENTITY_ID = 'NNNNNN' и intfc_inst = 14; ОБНОВИТЕ UPDATE_DATE НАБОРА shhhyh.cash_activity = sysdate, USER_CHAR1 = TO_CHAR (SYSDATE, 'AM MM/DD/YYYY HH:MI:SS'), USER_CHAR2 = 'UPDATESCRIPT', ГДЕ entity_id = (выбирают entity_id из shhhsyh.cash_activity ГДЕ CASH_INT = 41166153 И ENTITY_ID = 'NNNNN' и src_intfc_inst = 14); ~ –  Nirmal Arri 04.10.2012, 22:08
  • 5
    я хочу взять все от первого ОБНОВЛЕНИЯ до первого, ГДЕ и заменяют его: вставьте в выбор nncknn.cash_activ_02_tmp * от nnhfjfn.cash_activity где –  Nirmal Arri 04.10.2012, 22:11

Теги

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