简体   繁体   中英

How to delete a part of the text file if a pattern is found matching using tcl?

How can I remove a part of the text file if the pattern I am searching is matched?

eg:

  pg_pin (VSS) {
  direction : inout;
  pg_type : primary_ground;
  related_bias_pin : "VBN";
  voltage_name : "VSS";
}
leakage_power () {
  value : 0;
  when : "A1&A2&X";
  **related_pg_pin** : VBN;
}

My pattern is related_pg_pin. If this pattern is found i want to remove that particular section(starting from leakage power () { till the closing bracket}).

proc getSection f {
    set section ""
    set inSection false
    while {[gets $f line] >= 0} {
        if {$inSection} {
            append section $line\n
            # find the end of the section (a single right brace, #x7d)
            if {[string match \x7d [string trim $line]]} {
                return $section
            }
        } else {
            # find the beginning of the section, with a left brace (#x7b) at the end
            if {[string match *\x7b [string trim $line]]} {
                append section $line\n
                set inSection true
            }
        }
    }
    return
}

set f [open data.txt]
set g [open output.txt w]
set section [getSection $f]
while {$section ne {}} {
    if {![regexp related_pg_pin $section]} {
        puts $g $section
    }
    set section [getSection $f]
}
close $f
close $g

Starting with the last paragraph of the code, we open a file for reading (through the channel $f ) and then get a section. (The procedure to get a section is a little bit convoluted, so it goes into a command procedure to be out of the way.) As long as non-empty sections keep coming, we check if the pattern occurs: if not, we print the section to the output file through the channel $g . Then we get the next section and go to the next iteration.

To get a section, first assume we haven't yet seen any part of a section. Then we keep reading lines until the end of the file is found. If a line ending with a left brace is found, we add it to the section and take a note that we are now in a section. From then on, we add every line to the section. If a line consisting of a single right brace is found, we quit the procedure and deliver the section to the caller.

Documentation: ! (operator) , >= (operator) , append , close , gets , if , ne (operator) , open , proc , puts , regexp , return , set , string , while , Syntax of Tcl regular expressions

Syntax of Tcl string matching:

  • * matches a sequence of zero or more characters
  • ? matches a single character
  • [chars] matches a single character in the set given by chars (^ does not negate; a range can be given as az )
  • \\x matches the character x , even if that character is special (one of *?[]\\ )

Here's a "clever" way to do it:

proc unknown args {
    set body [lindex $args end]
    if {[string first "related_pg_pin" $body] == -1} {puts $args}
}
source file.txt

Your data file appears to be Tcl-syntax-compatible, so execute it like a Tcl file, and for unknown commands, check to see if the last argument of the "command" contains the string you want to avoid.

This is clearly insanely risky, but it's fun.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM