2015-12-24 5 views
0
патча в

Моей строки, как следующее:Tcl: ошибка при использовании команды

str1.str2.strn-1.{i}.strn

Я использую команду sed, чтобы удалить строку после последней точки «»

proc check_str {str} { 

set cmd "echo $str | sed -E 's/[^.]+$//'" 

set new_str [exec sh -c $cmd] 
puts "the new string is :$new_str" 
} 

Но я получил сообщение об ошибке:

invalid command name ^.

и новая строка не отображается!

Как я могу отобразить новую строку?

+0

По правде говоря, Tcl/Tk предоставляет механизмы для обработки регулярных выражений, не требуя ничего такого неуклюже, как выполнение внешней команды, чтобы справиться с ним. –

+0

так что альтернативное решение с tcl? –

+0

Вы задавали много довольно простых вопросов о обработке строк. Я бы порекомендовал вам потратить некоторое время на [учебник Tcl] (http://tcl.tk/man/tcl8.5/tutorial/tcltutorial.html) и [страницы руководства Tcl] (http://tcl.tk /man/tcl8.6/TclCmd/contents.htm) - вы скоро сможете ответить на свои вопросы. –

ответ

2

Команда regsub соответствует регулярному выражению и применяет подстановку к совпадающему тексту. Это очень похоже на то, что вы делаете с sed s.

set new_str [regsub {[^.]+$} $str ""] 

Обратите внимание, что это почти всегда важно, чтобы регулярные выражения в фигурных скобках (которые в Tcl очень похожи на одинарные кавычки в Unix оболочек), так как они обычно содержат Tcl метасимволы. В этом случае регулярное выражение содержит [, ] и $ (хотя в терминальном положении); он должен быть процитирован, или Tcl попытается выполнить странно названную команду. ^. Он также может быть процитирован с обратными косыми чертами, но это становится раздражающим и неясным.

И это также было не так с вашей предыдущей попыткой в ​​вашем вопросе. Использование exec sed для этого является излишним излишеством. Использование exec echo … | sed еще хуже, так как делает это изнутри sh -c. Правильный инструмент под рукой и намного эффективнее (учитывая, что вы уже находитесь в Tcl).

1

Я нашел решение с Tcl:

regsub -- {[^.]+$} $str {} string 
1

Другой метод Tcl бы разделить эту строку в список слов, используя точку в качестве разделителя. Замените последнее слово пустой строкой. Объедините слова вместе.

set str {str1.str2.strn-1.{i}.strn} 
set words [split $str .] 
lset words end "" 
set new [join $words .] # => str1.str2.strn-1.{i}. 

Еще один способ - найти индекс последней точки в строке. Затем возьмите подстроку от нуля до этого индекса

set new [string range $str 0 [string last . $str]] 

IMO даже regsub является излишним для выполнения этой задачи.

+1

'regsub' примерно на 25% быстрее, даже при нажатии вашей версии в максимально скомпилированный режим. Но эта версия файла «root» намного быстрее; на ~ 275% быстрее, чем версия 'regexp' и ~ 370% быстрее, чем ваша. –

+0

, что меня удивляет, но хорошо знать –

1

Существует команда, которая делает почти то, что вы хотите, за исключением того, что она удаляет последнюю точку, а также - но это легко исправить, добавив новую точку в конце:

set new [file rootname $str]. 
# => str1.str2.strn-1.{i}. 

Документация: file

Смежные вопросы