bash - 压缩多个文件,从变量中获取参数,其中一个文件的名称为 space

bash - zip multiple files, take argument from variable, one of them has space in name

我想压缩 file.txtfile with spaces.txt。我需要将它们保存在一个变量中。我可以像这样连接这些字符串:

files="$files \"$newfilename\""

然后我将所有文件名放在一个变量中,用 space 分隔,每个文件名都用引号括起来。 "file.txt""file with spaces.txt"

所以我现在需要压缩它们。 但是如果我这样做:

tar czf output $files

然后 bash 将产生:

tar czf output '"file.txt."' '"file' with 'spaces.txt"'

如果我这样做

tar czf output "$files"

然后 bash 会做:

tar czf output '"file.txt." "file with spaces.txt"'

在第一种情况下,bash在每个单词前后插入一个撇号,在第二种情况下,tar将两个文件作为一个名称。如果 $files 变量中正好有这个字符串,我应该怎么做才能生成 tar czf "file.txt" "file with spaces.txt"

使用变量存储独立的多词条目。使用数组并正确引用文件名,以便保留带空格的名称

declare -a files=()
files=("file.txt")
files+=("file with spaces.txt")

+=() 用于将元素附加到现有数组。现在扩展数组是您需要将列表传递给 zip

tar czf output "${files[@]}"

关于 OP 关于执行 files=()declare -a files=() 之间的上下文的问题。它们可能是同一件事,并且在初始化索引数组的相同上下文中工作。但是当你在没有 () 部分的情况下执行 declare -a files 时,会发生明显的差异。因为 declare -a 而不是 重新初始化一个已经定义的数组,但 =() 清空它。参考下面的例子

prompt> files=()
prompt> files+=(a "new word")
prompt> files+=("another word")
prompt> echo "${files[@]}"
a new word another word

现在做 files=() 会完全清空现有数组,

prompt> files=()                   # array completely emptied now
prompt> echo "${files[@]}"
                                   # empty result

但内容和之前一样

prompt> echo "${files[@]}"
a new word another word
prompt> declare -a files           # an existing array is not emptied
prompt> echo "${files[@]}"
a new word another word