2015-09-07 4 views
0

У меня есть следующий код в большой файлЗамена четырех линий с SED

} 
    catch (PDOException $e){ 
     echo 'Error: '. $e->getMessage(); 
    } 

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

Следующая который я думал, что должен работать не работает:

sed '1N;$!N;s/.*}.*\n.*catch.*\n.*Error.*\n.*}.*//;P;D' myfile.php 

Странная вещь, что

sed '1N;$!N;s/.*}.*\n.*catch.*\n.*Error.*//;P;D' myfile.php 

удаляет первые три строки. И

sed '1N;$!N;s/.*catch.*\n.*Error.*\n.*}.*//;P;D' myfile.php 

удаляет последние три строки.

Почему это не работает для всех четырех линий?

Я также не совсем понимаю, зачем мне нужен $! N, чтобы это работало, поэтому, если вы можете объяснить, что именно это делает, это также поможет моему пониманию.

Спасибо!

+0

'sed' лучше всего подходит для соответствия линии. Для многострочной линии лучше использовать Perl. Кроме того, см. [Как использовать sed для замены многострочной строки?] (Http://unix.stackexchange.com/q/26284/40596) – fedorqui

+0

Вы получите синтаксическую ошибку PHP, если вы сохраните блок try но удалите блокирующий блок. – hek2mgl

ответ

1

Это может работать для вас (GNU СЭД):

sed ':a;N;s/\n/&/3;Ta;/^\s*}\n.*catch.*\n.*Error.*\n\s*}$/d;P;D' file 

Это решение сделать скользящее окно из четырех линий в шаблоне пространства (PS), и если нужный шаблон совпадает с PS эти четыре строки будут удалены , В противном случае первая строка будет напечатана, а затем удалена, а другая добавлена ​​к PS, и совпадение повторится до тех пор, пока не будет достигнуто совпадение или конец файла.

N.B. sed по дизайну удаляет любые новые строки перед заполнением PS. команда N добавляет новую строку, а затем следующую строку к PS.Если команда N вызывается после окончания файла, дальнейшие команды не выполняются и PS печатается (если только не включена опция -n).

+0

Это отлично работает! Спасибо. Просто пытаюсь понять это сейчас. :) – kojow7

+0

Думаю, я все понимаю, кроме части '/ &/3; Ta'. Вы можете объяснить, что там происходит? – kojow7

+1

@ kojow7 подстановка с использованием' Команда s /.../.../ 'может использоваться для замены определенного совпадения шаблона соответствия (lefthandside или lhs). В этом случае lhs является новой строкой, а сама замена является механизмом подсчета количество строк новой строки. Команда 'T' может использоваться для разветвления h к держателю места (в данном случае 'a'), если замена была неудачной (двойным для этого является команда' t' для успешной замены). Таким образом, по сути, sed-скрипт продолжает цикл, пока пространство шаблона не содержит 3 строки новой строки (4 строки). если используется ': a; N; s/\ n/&/3; Ta'. – potong

0

Как я уже сказал, here, вы получите синтаксическую ошибку в PHP, если вы удалите блокирующий блок.

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

<?php 

$string = <<<'EOF' 
    } 
    catch (PDOException $e){ 
     echo 'Error: '. $e->getMessage(); 
    } 
EOF; 

// Check http://php.net/manual/de/regexp.reference.recursive.php 
$pattern = '/catch .*\{(((?>[^{}]+)|(?R))*)\}/'; 

echo preg_replace($pattern, '', $string); 

sed не делает шаблон рекурсии таким образом.

+0

Я знаю, что я не могу использовать блок try без блока catch. Я смог удалить попытку просто отлично, это блокировка, которую я не смог удалить. У меня есть сотни файлов, которые я хочу удалить из блока try/catch, поэтому использование php будет более сложным, чем просто использование простой команды sed. – kojow7

+0

Большим преимуществом приведенного выше кода является то, что он соответствует блокам между '{}' рекурсивно. Значение любой, если, переключить или любой блок в блоке catch. Итерация через кучу файлов легко возможна с помощью PHP. Должен ли я показать это? – hek2mgl

+0

Добро пожаловать, чтобы показать это, однако, это не связано с моим вопросом. Мне было интересно узнать, как это сделать в sed, о котором уже сказал potong. Если бы я был открыт для этого, я бы не упомянул о sed. Кроме того, если вы посмотрите на код, который я разместил, мне не нужна рекурсия. Тем не менее, это может помочь с будущей задачей, которую мне нужно сделать, поэтому я обязательно буду помнить об этом. – kojow7

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