Perl 将图案从特定行移动到该规则的末尾
我想知道如何将放置在某一行之后的图案移动到规则的另一个位置 考虑下面的例子Perl 将图案从特定行移动到该规则的末尾,perl,shell,tcl,Perl,Shell,Tcl,我想知道如何将放置在某一行之后的图案移动到规则的另一个位置 考虑下面的例子 rule tmap { hideON student_analysis Sam -expr "marks(Sam)" -gt 0 hideOFF -Designate [ School = "ABC] -Designate [ Name = "Sam" ] -Designate [ Country= "ABC] -Designate [ State = "Sam"] -Design
rule tmap {
hideON
student_analysis Sam -expr "marks(Sam)" -gt 0
hideOFF
-Designate [ School = "ABC]
-Designate [ Name = "Sam" ]
-Designate [ Country= "ABC]
-Designate [ State = "Sam"]
-Designate [ ROLL Number= "Sam"]
}
其中hideOFF需要从student_分析移动到刚好在结束花括号之前。输出文件应该有如下内容
rule tmap {
hideON
student_analysis Sam -expr "marks(Sam)" -gt 0
-Designate [ School = "ABC]
-Designate [ Name = "Sam" ]
-Designate [ Country= "ABC]
-Designate [ State = "Sam"]
-Designate [ ROLL Number= "Sam"]
hideOFF
}
只需添加这些-指定项就可以在一行中,所以行数不应作为标准。我的输入文件可能是这样的
rule tmap {
hideON
student_analysis Sam -expr "marks(Sam)" -gt 0
hideOff
-Designate [ School = "ABC] -Designate [ Name = "Sam" ] -Designate [ Country= "ABC] -Designate [ State = "Sam"] -Designate [ ROLL Number= "Sam"]
}
如果你需要更多的澄清,请让我知道
基于Peters帮助的最终解决方案
#!/usr/bin/tclsh
set fileData [lindex $argv 0 ]
set fp [open $fileData r]
set data [read $fp]
set lines [split [string trim $data] \n]
set hideoff {}
foreach line $lines {
if {[regexp {^\s*hideoff\s*} $line match ] == 1 } {
set hideoff $line
} elseif {[regexp {^\s*\}\s*} $line match ] == 1 } {
puts $hideoff
puts $line
} else {
puts $line
}
}
谢谢大家的建议。在VIM中测试了以下正则表达式,它完全满足您的要求:
%s/hideOFF\(\_.*\)}/\1\rhideOFF\r}/i
**Explanation:**
%s - Search across the file
\( \) - Used to capture a group of text to be used in replace section
\_.* - Capture everything, including new lines
\1 - Insert captured group here
\r - new line
我提到了以下两个来源:
&
原文:
在正则表达式之后:
您可以使用在所有Unix/Linux变体中可用的,以简单/单行的形式实现这一点
printf '%s\n' '/hideOFF' 'd' '/}' '-' 'put' 'wq' | ex file
ex
编辑器结构类似于vi
的语法。我为此采用的逻辑如下(请记住,就像在vi
/vim
中打开文件一样)
hideOFF
搜索为'/hideOFF'
,使用d
命令键将其删除/}
,-
和put
将寄存器中的行写入大括号上方wq
将内容写回文件$ cat file
rule tmap {
hideON
student_analysis Sam -expr "marks(Sam)" -gt 0
hideOFF
-Designate [ School = "ABC]
-Designate [ Name = "Sam" ]
-Designate [ Country= "ABC]
-Designate [ State = "Sam"]
-Designate [ ROLL Number= "Sam"]
}
直接在命令行上运行命令:-
$ printf '%s\n' '/hideOFF' 'd' '/}' '-' 'put' 'wq' | ex file
$ cat file
rule tmap {
hideON
student_analysis Sam -expr "marks(Sam)" -gt 0
-Designate [ School = "ABC]
-Designate [ Name = "Sam" ]
-Designate [ Country= "ABC]
-Designate [ State = "Sam"]
-Designate [ ROLL Number= "Sam"]
hideOFF
}
(Tcl解决方案)
你可以通过重印行来做到这一点。首先查看它们,跳过要移动的行,然后在看到要插入的行时打印
set lines [split [string trim $data] \n]
set hideoff {}
foreach line $lines {
if {[string trim $line] eq "hideOFF"} {
set hideoff $line
} elseif {[string trim $line] eq "\}"} {
puts $hideoff
puts $line
} else {
puts $line
}
}
另一个Tcl解决方案:
regsub -all {(\s*hideOFF)([^\}]+)} $data \\2\\1\n
这两种解决方案都适用于多个块
文件:
,
,
,
,
,
,
,
,
您需要重新编写文件,一旦您这样做,使用任何语言都非常简单 逐行复制到一个新文件中。当到达
hideOFF
行时,不要将其写入新文件,只需保存到变量中即可。然后,当你到达该块的右大括号时,写出变量(带行)和大括号。这将使带hideOFF
的行移到带大括号的行之前
你需要一个标志来知道你何时进入和离开一个街区
请尝试一下,并让我们知道它是如何运行的。您是否尝试解决此问题,您在哪里失败了?我还没有为此编写任何代码。我只是想知道以前是否有人遇到过类似的事情。@Togi:你至少应该试试。堆栈溢出是一个帮助的来源,而不是一个免费完成工作的地方。谢谢。不幸的是,该解决方案只适用于第一种模式,而铰孔模式保持原样。@Devhratogi:您在问题中只提供了一种模式。你说剩下的图案是什么意思?谢谢J阿特瓦尔。这是一个有趣的解决方案,但只适用于最后两种模式。我的文件中大约有11K行,8k行包含相同的模式。@托吉:你的问题根本没有提到这一点。我们应该如何预测您未提供的信息?使用tcl解决方案以及问题声明解决了此问题。#/usr/bin/tclsh set fileData[lindex$argv 0]set fp[open$fileData r]set data[read$fp]set lines[split[string trim$data]\n]set hideoff{}foreach line$lines{if{[regexp{^\shideoff\s}$line match]=1}{set hideend$line}elseif{[regexp^\s*}\s*\s*}$line match]=1}{否则{put$line}谢谢彼得。我用regexp替换了string trim,它对我的案例有效。谢谢你的帮助。