在多行中整齐地列出值

问题描述 投票:0回答:4

如何在多行中列出值而不在每行末尾添加反斜杠?

如果末尾没有反斜杠,就无法创建多行列表。
例如,以下(错误)代码:

set pets [list 
    cat
    dog
    elephant
]

给出错误:

invalid command name "cat"
    while executing
"cat"
    invoked from within
"set pets [list
        cat
        dog
        elephant
]"

可以通过在行尾添加反斜杠来修复:

set pets [list \
    cat \
    dog \
    elephant \
]

这很难看并且容易出错。

请注意:

  • 我知道使用大括号(
    {
    }
    ),但它不允许执行命令并且还保留多余的空白字符。
  • 可以使用任何其他命令(例如
    dict create
    ),而不仅仅是我的示例中的
    list

使用Tcl 8.5

tcl
4个回答
23
投票

Tcl 使用换行符(和分号)作为命令分隔符。这是基本语法的核心部分;你无法解决它,所以你必须使用双引号或大括号来避免反斜杠炎。让我们看看可能性(记住,列表分隔符可以是任何非空空白序列)。

丑陋,容易出错
list
带有反斜杠

set pets [list \
    cat \
    dog \
    $elephant \
]

带大括号,无需替换

set pets {
    cat
    dog
    $elephant
}

(请注意,在上面,

$elephant
只是一个字符序列,不是读取的变量。)

用双引号,替换但要小心!

set pets "
    cat
    dog
    $elephant
"

“小心!”我的意思是,如果列表中有多个单词的成员,则需要内部

[list …]
或其他引用:

set pets "
    cat
    dog
    [list $elephant]
    [list "elephant's child"]
"

但是如果顶部有

list
+反斜杠,情况就是如此。

使用
subst

set pets [subst {
    cat
    dog
    $elephant
    "elephant's child"
}]

我可能会通过以下方式“清理它”(并避免其他潜在问题):

set pets [list {*}[subst {
    cat
    dog
    [list $elephant]
    [list "elephant's child"]
}]]

但坦率地说,如果事情变得非常复杂,那么我实际上会这样做:

使用多个命令进行构建

set pets {
    cat
    dog
}
lappend pets $elephant "elephant's child"

当两个或更多命令可以完成所有事情并且问题较少时,没有必要为了使用一个命令而苦恼。


2
投票

有时只需制作多个重叠线来分割线就可以“整齐”。

set pets ""
lappend pets cat
lappend pets dog
lappend pets elephant

foreach pet $pets {
   puts "I like to eat ${pet}s"
}

1
投票

这是一个名为

lines
的过程,它可能会满足您的需求 -

proc lines {lines} {
    foreach item [uplevel [list subst -nobackslash $lines]] {
        lappend list $item
    }
    return $list
}

这里是它的使用演示—

set another_pet fish;

set pets [lines {
    cat
    [string range hotdog 3 end]
    elephant
    $another_pet
    "african pygmy hedgehog"
    snapping\ turtle
    "\"henry\" the bengali tiger"
}]

puts $pets

它根据需要输出,

cat dog elephant fish {african pygmy hedgehog} {snapping turtle} {"henry" the bengali tiger}

如果你想用叉子玩一玩,Ideone 就在这里


0
投票

这花了我一整天的时间,但最终很简单(当然)。

proc render {infile outfile} {
    global ffconfig

    # ffmpeg options
    set a {                 
    -hide_banner                  
    -loglevel $ffconfig(loglevel) 
    -i $infile                    
    -tune $ffconfig(tune)         
    -movflags $ffconfig(movflags) 
    -preset $ffconfig(preset)     
    -c:v $ffconfig(vcodec)        
    -maxrate $ffconfig(max_rate)  
    -bufsize $ffconfig(buffsize)  
    -c:a $ffconfig(acodec)        
    -c:s $ffconfig(scodec)        
    -threads $ffconfig(threads)
    }

    # turn into an executable command line
    
    set b [list {*}$a];      # turn into a list of strings
    set c [subst $b];        # substitute values for variables
    puts stderr \[$c\]      # see below
    
    exec -- ffmpeg {*}$c $outfile ;

subst 命令获取列表并将其处理为 将所有变量替换为其值,如下所示:

[-hide_banner -loglevel {error} -i {The.Astrologer.1976.mkv} -tune {film} -movflags {faststart} -preset {slow} -c:v {libx264} -maxrate {8192} -bufsize {8000k} -c:a {copy} -c:s {copy} -threads {2}]  

{*}$c 命令扩展列表元素。

© www.soinside.com 2019 - 2024. All rights reserved.