В Tcl элемент списка в кавычках с последующим ")" вместо пробела

Этот вопрос может быть дубликатом этого вопроса, но проблема, с которой я сталкиваюсь, не имеет отношения к этому ответу. Я пробовал код, который люди там размещали, но я не могу добиться того, чего хочу. Мой код:

set line H_Dev: Issue with DELETE funtion in OSPF OC (Input List is missing required key "identifier") 
foreach {name value} [string map {( { } ) {} } $line] {
    puts "$name $value"
}

код выше не работает, но после включения { }

set line {H_Dev: Issue with DELETE funtion in OSPF OC (Input List is missing required key "identifier")} 

это работает так

H_Dev: Issue
with DELETE
funtion in
OSPF OC
Input List
is missing
required key
identifier

но в моем скрипте строка $ находится только в списке. как получить простой текст, как это

H_Dev: Issue with DELETE funtion in OSPF OC Input List is missing required key identifier

2 ответа

Проблема в этой строке:

set line H_Dev: Issue with DELETE funtion in OSPF OC (Input List is missing required key "identifier") 

Поскольку вы ничего не цитировали, вы передаете много аргументов set (что приведет к ошибке, так как не будет так много аргументов), или будет, кроме "identifier") Похоже, это слово в двойных кавычках, за исключением того, что это не из-за ) после закрытия " и это является причиной ошибки.

Обычные исправления - двойная кавычка всей строки (с обратным слешем перед любыми внутренними двойными кавычками):

set line "H_Dev: Issue with DELETE funtion in OSPF OC (Input List is missing required key \"identifier\")"

или поставить всю партию в фигурные скобки (что делает гнездо очень простым):

set line {H_Dev: Issue with DELETE funtion in OSPF OC (Input List is missing required key "identifier")}

Чтобы получить только те слова, которые вы хотите, вы можете использовать string map удалить ненужных персонажей, regsub -all удалить нежелательных персонажей, или regexp -all -inline выбрать нужные слова.

Вариант первый:

set line [string map {{"} {} ( {} ) {}} $line]

Вариант второй:

set line [regsub -all {[("")]} $line ""]

Вариант третий:

set line [regexp -all -inline {[\w]+:?} $line]

Я предпочитаю выбирать слова, которые я хочу, вместо того, чтобы фильтровать символы, которые мне не нужны, поскольку это менее удивительно при неожиданных входных данных. Другие люди не согласны со мной.

Вы правы в том, что вам нужны фигурные скобки (или кавычки, которые не будут работать в вашем случае, потому что у вас есть кавычки в строке) вокруг вашей строки, если вы хотите назначить ее переменной с помощью команды "set". Если у вас нет фигурных скобок, то команда "set" передает слишком много аргументов. Проблема заключается в следующем:

foreach {name value} [string map {( { } ) {} } $line] {
  puts "$name $value"
}

Это просматривает вашу строку по два слова за раз, присваивая их переменным "имя" и "значение" и печатая каждую пару в одной строке. Если вы просто хотите напечатать всю строку, избавьтесь от строки foreach и просто сделайте это:

puts $line

Если вы также пытаетесь избавиться от скобок и скобок (как это выглядит в вашем коде), вы можете сделать это:

puts [string map {( { } ) {} } $line]
Другие вопросы по тегам