TCL изменяет или удаляет точную комбинацию символов из строки

#tcl

#tcl

Вопрос:

При удалении файла я пытаюсь переименовать все файлы по номеру приращения переменной.

У меня есть список файлов. Каждый из них имеет шестнадцатеричное имя и увеличивается в зависимости от количества файлов в папке; когда в этой папке создается новый файл.

312d416e64207768657265206172652077652e2e20f09f8e88 ;# 1-имя файла — 1-й файл 332df09f8eb220556e64657220436f6e737472756374696f6e20f09f8eb2;# 2-имя файла 2-го файла 332df09f8cb22043686e6167654c6f6720f09f8cb2 ;# 3-имя файла 3-го файла

Я пытаюсь удалить первые четыре или комбинацию: 3x2d из каждого из этих файлов, а затем переименовать их в правильной последовательности

Мой код выглядит следующим образом:

 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
}
 

Это работает так же точно, как и есть, и это именно тот результат, который я хочу

Однако он продолжает обрезать любое число «2»

332df09f8eb220556e64657220436f6e737472756374696f6e20f09f8eb2

Это приводит к нарушению шестнадцатеричного кода, если вы должны были декодировать его обратно в ascii.

Использование regsub. Это работает, но дает странные результаты.

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

в результате чего получается что-то вроде:

372d382d f09f8cb22043686e6167654c6f6720f09f8cb2;# результат: 7-8-имя файла

Я предполагаю, что это потому, что я удаляю строку «3x2d» из строки каждый раз цикла цикла.

tl; dr: хотите удалить «312d» из имени файла, а затем переименовать файл с правильным увеличенным числом, основанным на количестве каталогов, разделенных символом «-»

приветствия

Ответ №1:

string trim Команда обрабатывает свой второй аргумент как набор символов для удаления и продолжает удалять их с обоих концов строки, пока не останется ни одного. Чтобы просто удалить из левого конца строки, есть 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 ""]
 

Будьте очень осторожны при построении регулярных выражений. Хотя вы в порядке с шестнадцатеричными символами, легко попасть в затруднительное положение, если у вас есть ПОВТОРНО метасимволы в ваших компонентах шаблона.


Для наглядности, вероятно, лучше всего создать вспомогательную процедуру.

 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]
 

Комментарии:

1. Однако, спасибо, это работает в обратном направлении, как я этого хочу. Используя процедуру RemovePrefix, я получаю вывод типа: переименовать из 332df09f8eb220556e64657220436f6e737472756374696f6e20f09f8eb2 в 322d, когда я хочу удалить 322d, оставив 09f8eb220556e64657220436f6e737472756374696f6e20f09f8eb2