TCL Alter or Remove an exact character combination from a string

时间:2019-04-16 22:36:12

标签: tcl

On deletion of a file, I am trying to rename all files by the increment number of a variable.

I have a list of files. Each are named in hexadecimal and incremented based on how many files in the folder; when a new file is created in that folder.

312d416e64207768657265206172652077652e2e20f09f8e88 ;# 1-filename - 1st file 332df09f8eb220556e64657220436f6e737472756374696f6e20f09f8eb2 ;# 2-filename 2nd file 332df09f8cb22043686e6167654c6f6720f09f8cb2 ;# 3-filename 3rd file

I am trying to remove the first four or the combination of: 3x2d from each of these files and then rename them with the correct sequence

My code is as follows:

set symbol [ixc::2Hex "-"] ;# 2d
set contents [glob -directory $dir *]
append sorted [lsort -dictionary $contents]

foreach item $sorted {
incr baseCount
set ze [file tail $item]

set hexCount [ixc::2Hex "$baseCount"] ;#convert ascii to hex
set hexZe "[string trim $ze "$hexCount$symbol"]" ;#trim the hexcount and delmiter from the file name
#set hexZe [regsub "$hexCount$symbol" $ze ""] ;#Alternative way of removing characters but buggy

puts "rename >> $item to $hexCount$symbol$hexZe" 
puts "----"

# catch the error if the "cannot rename same file" 
# this occurs when the file deletes 
# then rename tries to rename the same file as the same file

if { [catch {file rename $item $dir/$hexCount$symbol$hexZe} error] } {
continue
} else {
set fexist "$item"

#rename the file as the hexValue based off the counted ascii value 
#include the symbol and file name
#if the file does not exist such as the deleted file then skip

if { $fexist eq 1} { 
file rename $item $dir/$hexCount$symbol$hexZe   
} else { 
continue
}

This works as exactly as it does and is exactly the result I want

However it proceeds to trim any number of "2"

332df09f8eb220556e64657220436f6e737472756374696f6e20f09f8eb2

This resulting in broken hex if you were to decode it back in to ascii.

Using regsub. It works but provides funky results.

set hexZe [regsub "$hexCount$symbol" $ze ""]

resulting in something like:

372d382df09f8cb22043686e6167654c6f6720f09f8cb2 ;# result: 7-8-filename

I assumes it's because I'm removing the string "3x2d" from the string each time of cycle of the loop.

tl;dr: want to remove "312d" from the file name, and then rename the file with the correct incremented number based on the count of the directory seperated by a "-"

cheers

1 个答案:

答案 0 :(得分:0)

string trim命令将其第二个参数视为要删除的字符的 set 集,并继续从字符串的两个末尾删除它们,直到没有离开了。要仅从字符串的左端删除,请使用string trimleft,但在这种情况下,最好使用以下任一方法:

# Save a copy of the string to remove in a variable for convenience
set pattern $hexCount$symbol

# How to do an exact prefix match
if {[string equal -length [string length $pattern] $pattern $ze]} {
    set hexZe [string range $ze [string length $pattern] end]
} else {
    # If it didn't match, fall back
    set hexZe $ze
}

或:

# NOTICE THE ANCHOR! Only want to do this *at the start of the string*
set hexZe [regsub "^$hexCount$symbol" $ze ""]

在构造正则表达式时要非常小心。如果您对十六进制字符感到满意,但是如果您的模式组件中有RE元字符,那么很容易就没问题。


为清楚起见,最好创建一个帮助程序。

proc RemovePrefix {string prefix} {
    set length [string length  $prefix]
    if {[string equal  -length $length  $prefix $string]} {
        return [string range  $string  $length end]
    }
    return $prefix
}

set hexZe [RemovePrefix $ze $hexCount$symbol]