我想知道如何将某个行之后放置的模式移动到规则的另一个位置。
考虑以下示例,
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_analysis移动到结束花括号之前。输出文件应该类似于
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
}
只是添加这些--Designate条目可能在一行中,因此行数不应成为标准。我可能有我的输入文件,如
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
}
}
感谢大家提出的好建议。
答案 0 :(得分:1)
您可以使用所有Unix / Linux变体中提供的ex
text-editor来实现此目的,简单/单行
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
}
答案 1 :(得分:1)
你需要重新编写文件,一旦你这样做,任何语言都很简单。
逐行浏览并将其复制到新文件中。当你来到hideOFF
行不要将它写入新文件时,只需保存到变量中即可。然后,当你到达那个块的右括号时,写出变量(带有线)和大括号。这将使hideOFF
的线移动到支撑线的前面。
您需要一个标志才能知道您何时进入和离开区块。
请尝试一下,让我们知道它是怎么回事。
答案 2 :(得分:0)
在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
我提到了以下两个来源:
http://vim.wikia.com/wiki/Search_across_multiple_lines& Vim Regex Capture Groups
在Regex之后:
答案 3 :(得分:0)
(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
两种解决方案都适用于多个块。
文档: eq (operator), foreach, if, puts, regsub, set, split, string, Syntax of Tcl regular expressions