2013-11-13 2 views
1

Извините, если заголовок недостаточно описательный, но я действительно не знаю, как его суммировать, и любые предложения приветствуются. Я написал полезный кусок регулярного выражения для соответствия строк в файлах sql, которые вставляют данные в определенные таблицы (содержащие кеш). Это выглядит следующим образом:Regex, который не работает с sed

(--\s--\sDumping\sdata\sfor\stable\s`(cache_\w+|cache)`.*?)(?=(--\n--.+Table\sstructure\sfor\stable\s`.+`.*--)) 

Так что теперь, когда у меня есть файл, как это:

-- 
-- Table structure for table `cache_content` 
-- 

something 

-- 
-- Dumping data for table `cache_content` 
-- 

INSERT INTO `cache_content` etc. 


-- 
-- Table structure for table `cache` 
-- 

something 

-- 
-- Dumping data for table `cache` 
-- 

INSERT INTO `cache` etc. 


-- 
-- Table structure for table `notcache` 
-- 

something 

-- 
-- Dumping data for table `notcache` 
-- 

Это соответствует все вставки в этих таблицах, и я хотел бы, чтобы удалить их (как те, таблицы с кэшем) с помощью sed, и, в частности, я написал простой Баш скрипт для этого:

REGEX="(--\s--\sDumping\sdata\sfor\stable\s\`(cache_\w+|cache)\`.*?)(?=(--\n--.+Table\sstructure\sfor\stable\s\`.+\`.*--))" 
sed -i "s/${REGEX}//g" $1 

Теперь проблема заключается в том, что она работает в моем регулярном выражении тестера, но он не работает на все с sed. sed просто не меняет файл вообще, и я оштрафован. Я где-то читал, что sed является линейным, но может ли это быть проблемой или что-то еще?

Добавлено # 1: Если с sed невозможно сделать то, что было бы хорошей альтернативой? Это что-нибудь подобное?

+1

Тот факт, что 'sed' основана линия является одной из ваших проблем , это также, вероятно, будет затруднено с '\ s' и' \ w' в вашем регулярном выражении. Вы можете захотеть использовать Perl или какой-то другой язык сценариев вместо bash/sed. –

+1

Вы также используете lookaheads, которые sed не поддерживает. – pobrelkey

ответ

2

Нет, вы не можете использовать sed, как это линия-ориентированный и ваш шаблон должен соответствовать по нескольким линиям. (Вы можете разбить шаблон на начальный шаблон и шаблон конца и попробовать /start_pattern/,/end_pattern/p, но тогда вам понадобится отдельный start_pattern s для каждой из ваших таблиц, потому что диапазон строк в sed может совпадать только один раз на входе.)

вы должны иметь возможность принять упрощенный запуск образца/конечный шаблон подход в awk:

awk 'BEGIN { x = 1 }; /^-- Dumping data for table `cache(_[a-zA-Z0-9]+)?`$/ { x = 0 }; /^-- Table structure for table `[^`]+`$/{ x = 1 }; (x == 1) { print }' $1 

Или вы могли бы еще взять один-Ginormous-регулярное_выражение-более-весь-файл подход (с некоторыми незначительными модификации) на «реальном» языке сценариев:

ruby -e 'File.write(ARGV[0],File.read(ARGV[0]).gsub(/(--\s--\sDumping\sdata\sfor\stable\s`(?:cache_\w+|cache)`.*?)(?=(?:--\n--\s+Table\sstructure\sfor\stable\s`[^`]+`\s*\n--))/m,""))' $1 
+0

Этот код Ruby соответствует строкам просто отлично, но как удалить совпадение из файла, на месте? Не могли бы вы добавить это, пожалуйста? К сожалению, я не знаю Ruby, и этот фрагмент кода может быть полезен и для кого-то другого. –

+0

Отредактировано так, что теперь пример Ruby редактирует файл на месте. (Также оба примера теперь удаляют содержимое кеш-таблицы, а не сохраняют их и удаляют все остальное!) – pobrelkey

+0

Это очень удобный фрагмент для замены многострочного регулярного выражения на месте :). И это побудило меня изучить Ruby или Python поверх bash. Большое спасибо! –

0

Вместо СЭД, попробуйте использовать Perl:

perl -e 'undef $/; $_ = <>; s/YOUR_REGEX_HERE//gs; print' $1 
+0

Не работает -p для регулярного выражения в строке, поэтому в моем случае это было бы бесполезно? Я бы с удовольствием, если бы это сработало. –

+0

Вы правы, мои плохие, спасибо. Я исправил ответ, см. Выше. – glexey

1

Зачем создавать дополнительную работу, если вы можете избежать ее в первую очередь? :)

Просто не генерировать операторы для таблиц, которые не заинтересованы в Например, если вы используете MySQL:.

mysqldump --ignore-table=<...> --ignore-table=<...> 

Другие базы данных будут иметь такой же вариант.

+0

Спасибо за предложение, но это не для моих свалок :). Иногда кто-то может отправить мне свою базу данных, выгруженную по умолчанию, и тогда такой скрипт будет удобен. –

0

начать свой СЭД, сохраняя все в буфере так

sed "H 
$ { 
    x 
# your code here 
    } 
  1. H нагрузка каждой строки в буфер
  2. , когда последняя строка ($) происходит
  3. своп текущую строку буфера (так весь файл находится в вашей рабочей области)
  4. Ваш код работает со всей строкой.

Be careefful,^и $ являются первый и последний символ из файла, не больше линии Wich не отделены друг от друга \ п

Смежные вопросы