如何使用perl搜索两个连续的换行符(\ n)?或者更具体地说,为什么搜索\ n \ n即使它们存在也不成功?我有一个带有连续换行符的文件(用十六进制编辑器验证,它们不是返回等)但是perl似乎不接受这个正则表达式。
perl -pi -e's / \ n \ n / TEST / g'myfile.xml =无结果
我实际上是在尝试将一些代码插入到XML文件中,但是换行符位于中间,这样做最优雅的方式是什么?我想出了一个怪异的perl衬里,但双线馈送似乎导致失败。
我想从以下位置更改gtkrc文件的一部分:
GtkWidget::link-color = @link_color
GtkWidget::visited-link-color = @text_color
####################
# Color Definitions
####################
为:
GtkWidget::link-color = @link_color
GtkWidget::visited-link-color = @text_color
GtkWindow::resize-grip-height = 0
GtkWindow::resize-grip-width = 0
####################
# Color Definitions
####################
使用原始代码的一部分作为我的搜索词(在原始脚本的每行之前有标签,顺便说一句),我的查找和替换术语是:
color\n\n\t\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\n\t\# Color
color\n\n\tGtkWindow::resize-grip-height = 0\n\tGtkWindow::resize-grip-width = 0\n\n\t\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\n\t\# Color
我想出了这个丑陋的perl命令:
perl -pi -e 's/color\n\n\t\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\n\t\# Color/color\n\n\tGtkWindow::resize-grip-height = 0\n\tGtkWindow::resize-grip-width = 0\n\n\t\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\n\t\# Color/g' /usr/share/themes/Ambiance/gtk-2.0/gtkrc
编辑:更正了Zaid的代码:
perl -0777 -pi -e 's/color\n\n\t\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\n\t\# Color/color\n\n\tGtkWindow::resize-grip-height = 0\n\tGtkWindow::resize-grip-width = 0\n\n\t\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\n\t\# Color/g' /usr/share/themes/Ambiance/gtk-2.0/gtkrc
如前所述,似乎是\ n \ n导致问题,因为其他任何东西都可以被替换。有什么更好的方法呢?
我在Ubuntu 11.10上,命令将从shell脚本而不是perl脚本运行。
答案 0 :(得分:3)
您需要一次性加载整个文件,以便检测\n\n
。使用-0777
覆盖默认的逐行行为:
$ perl -0777 -pi -e 's/\n\n/TEST/g' myfile.xml
答案 1 :(得分:2)
当您打开文件进行读取时,默认情况下会逐行读取该文件。这是因为输入记录分隔符$/
设置为换行符。
由于你在换行符中打破了每一行“直线”,因此您无法在一行中连续找到两个换行符。
正如Zaid所说,解决这个问题的一种方法是使用-0
标志更改输入记录分隔符。只要新的输入记录分隔符与正则表达式没有部分匹配,您就可以了。 (只要您不尝试将.
与\n
匹配)。
让我们的正则表达式不那么可怕。除非使用#
修饰符,否则无需转义/x
。您不需要连续使用多个#
个字符,而是使用量词+, * or {x,y}
。
除了删除一个字符串然后放回一个字符串之外,还有一些选项可以避免两次输入相同的内容。
\K
作为简化的Look-behind断言(见上文)$1, $2 ...
捕获字符串并将其放回。在这种情况下,我的偏好是使用后面的断言来查找“color \ n \ n”字符串,然后查找“Color”注释。
perl -0777 -pwe 's/(?<=color\n\n)(?=[#\s]+Color)/INSERT\n\n/' /path/to/file
INSERT
当然是您要插入的文本,我为了便于阅读而删除了该文本。我还删除了-i
标记,以便您可以先试用它。