【问题标题】:Insert lines of code in a file after n numbers of lines using tcl使用 tcl 在 n 行之后在文件中插入代码行
【发布时间】:2013-12-29 02:12:34
【问题描述】:

我正在尝试编写一个 tcl 脚本,在找到正则表达式后我需要在其中插入一些代码行。 例如,在当前文件中找到最后一次出现的#define 之后,我需要插入更多的#define 代码行。

谢谢!

【问题讨论】:

  • 我有点不清楚你在问什么。您是在寻找编写这样一个脚本的策略,还是有一些特定的 Tcl 构造导致了问题?您在第一句中提到“查找正则表达式”,在第二句中提到“查找最后一次出现”。这些是完全不同的东西。

标签: tcl


【解决方案1】:

对文本文件进行编辑时,您将其读入并在内存中对其进行操作。由于您正在处理该文本文件中的代码行,因此我们希望将文件的内容表示为字符串列表(每个字符串都是一行的内容)。然后让我们使用lsearch(使用-regexp 选项)来查找插入位置(我们将在反向列表中执行此操作,因此我们找到last而不是第一个位置)和我们可以使用linsert 进行插入。

总的来说,我们得到的代码有点像这样:

# Read lines of file (name in “filename” variable) into variable “lines”
set f [open $filename "r"]
set lines [split [read $f] "\n"]
close $f

# Find the insertion index in the reversed list
set idx [lsearch -regexp [lreverse $lines] "^#define "]
if {$idx < 0} {
    error "did not find insertion point in $filename"
}

# Insert the lines (I'm assuming they're listed in the variable “linesToInsert”)
set lines [linsert $lines end-$idx {*}$linesToInsert]

# Write the lines back to the file
set f [open $filename "w"]
puts $f [join $lines "\n"]
close $f

在 Tcl 8.5 之前,样式略有变化:

# Read lines of file (name in “filename” variable) into variable “lines”
set f [open $filename "r"]
set lines [split [read $f] "\n"]
close $f

# Find the insertion index in the reversed list
set indices [lsearch -all -regexp $lines "^#define "]
if {![llength $indices]} {
    error "did not find insertion point in $filename"
}
set idx [expr {[lindex $indices end] + 1}]

# Insert the lines (I'm assuming they're listed in the variable “linesToInsert”)
set lines [eval [linsert $linesToInsert 0 linsert $lines $idx]]
### ALTERNATIVE
# set lines [eval [list linsert $lines $idx] $linesToInsert]

# Write the lines back to the file
set f [open $filename "w"]
puts $f [join $lines "\n"]
close $f

搜索所有索引(并在最后一个索引上加一个)是足够合理的,但是插入的扭曲非常难看。 (8.4 之前?升级。)

【讨论】:

  • 使用split [read $f] \n 读取文件内容时,您应该使用read 的-nonewline 选项以避免列表中出现多余的尾随空白元素。
  • @glenn 或回信puts -nonewline $f [join $lines \n]
【解决方案2】:

不完全是您问题的答案,但这是有助于编写 shell 脚本的任务类型(即使我的解决方案有点难看)。

tac inputfile | sed -n '/#define/,$p' | tac
echo "$yourlines"
tac inputfile | sed '/#define/Q' | tac

应该可以!

【讨论】:

  • 这个问题确实要求一个 Tcl 脚本,但这不是……
  • 您好,感谢您的回复,但是这个方法无效。你能建议我在得到行号后如何插入一些代码吗?之后我需要插入代码。假设最后一个#define 发生在第 1 行。 100 dn 如何仅使用 TCL 在 101 处插入代码。
  • 对 Tcl 的问题 asked 明确地和通过标记。如果您已将其定制为从 Tcl 运行(通过它的 exec 命令),您的响应可能是好的,但您没有。
  • 好的,感谢您从管辖权的角度正确...我仍然很高兴为 Tcl 答案提供了一个更简单的替代方案。
  • 而且您不会将结果写回。你也不处理错误情况(没有文件,没有匹配)。 Bash 脚本编写很容易,直到您必须处理令人讨厌的边缘情况,然后难度就变得更大了。另外,您实际上并没有在那里使用任何 bash 功能;任何 Unix shell 都会这样做。
【解决方案3】:
set filename content.txt
set fh [open $filename r]
set lines [read $fh]
close $fh


set line_con [split $lines "\n"]
set line_num {} 
set i 0
foreach line $line_con {
    if [regexp {^#define} $line] {
        lappend line_num $i
        incr i
    }
}

if {[llength $line_num ] > 0 } {
    linsert $line_con [lindex $line_num end] $line_insert
} else {
    puts "no insert point"
}


set filename content_new.txt
set fh [open $filename w]
puts $fh file_con
close $fh

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-12-13
    • 2012-08-17
    • 2013-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-14
    • 1970-01-01
    相关资源
    最近更新 更多