В 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]