【问题标题】:Bash substring expansion on array数组上的 Bash 子字符串扩展
【发布时间】:2013-11-23 09:46:38
【问题描述】:

我有一组带有给定后缀的文件。例如,我有一组后缀为.pdf 的pdf 文件。我想使用子字符串扩展获取不带后缀的文件名。

对于我可以使用的单个文件:

file="test.pdf"
echo ${file:0 -4}

要对所有文件执行此操作,我现在尝试了:

files=( $(ls *.pdf) )
ff=( "${files[@]:0: -4}" )
echo ${ff[@]}

我现在收到一条错误消息,提示 substring expression < 0..

(我想避免使用for 循环)

【问题讨论】:

    标签: arrays bash substr expansion


    【解决方案1】:

    使用parameter expansions 删除.pdf 部分,如下所示:

    shopt -s nullglob
    files=( *.pdf )
    echo "${files[@]%.pdf}"
    

    shopt -s nullglob 在使用 glob 时总是一个好主意:如果没有匹配项,它会使 glob 扩展为空。

    "${files[@]%.pdf}" 将扩展为一个数组,删除了所有尾随 .pdf。你可以,如果你想把它放在另一个数组中:

    files_noext=( "${files[@]%.pdf}" )
    

    对于文件名中的有趣符号(空格、换行符等),所有这些都是 100% 安全的,除了名为 -n.pdf-e.pdf-E.pdf 的文件的 echo 部分...但 @ 987654332@ 只是为了演示目的。你的files=( $(ls *.pdf) ) 真的很糟糕! 永远不要解析ls的输出


    回答您的评论:子字符串扩展不适用于数组的每个字段。摘自上面链接的参考手册:

    ${parameter:offset}

    ${parameter:offset:length}

    如果offset 的计算结果小于零,则该值用作与parameter 值末尾的偏移量。如果length 的计算结果小于零,并且parameter 不是@ 并且不是索引或关联数组,则它被解释为距parameter 值末尾的偏移量,而不是一个数字符,扩展是两个偏移量之间的字符。如果parameter@,则结果是length 从偏移开始的位置参数。 如果parameter 是由@* 下标的索引数组名称,则结果是数组中以${parameter[offset]} 开头的length 成员。 相对于比指定数组的最大索引大一。应用于关联数组的子字符串扩展会产生未定义的结果。

    所以,例如,

    $ array=( zero one two three four five six seven eight )
    $ echo "${array[@]:3:2}"
    three four
    $
    

    【讨论】:

    • 谢谢!完美运行:)
    • 这是否意味着子字符串扩展不适用于数组? (我也试过echo "${files[@]:0: -3}",还是不行)
    猜你喜欢
    • 2013-11-16
    • 1970-01-01
    • 2015-10-19
    • 2016-12-21
    • 1970-01-01
    • 2014-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多