简体   繁体   English

Bash子串在数组上的扩展

[英]Bash substring expansion on array

I have a set of files with a given suffix. 我有一组带有给定后缀的文件。 For instance, I have a set of pdf files with suffix .pdf . 例如,我有一组后缀为.pdf的pdf文件。 I would like to obtain the names of the files without the suffix using substring expansion. 我想使用子字符串扩展获取不带后缀的文件名。

For a single file I can use: 对于单个文件,我可以使用:

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

To do this operation for all files, I now tried: 为了对所有文件执行此操作,我现在尝试:

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

I now get an error saying that substring expression < 0 .. 我现在收到一条错误消息,说substring expression < 0 ..

( I would like to avoid using a for loop ) (我想避免使用for循环)

Use parameter expansions to remove the .pdf part like so: 使用参数扩展来删除.pdf部分,如下所示:

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

The shopt -s nullglob is always a good idea when using globs: it will make the glob expand to nothing if there are no matches. 使用glob时, shopt -s nullglob始终是一个好主意:如果没有匹配项,它将使glob扩展为零。

"${files[@]%.pdf}" will expand to an array with all the trailing .pdf removed. "${files[@]%.pdf}"将扩展为一个数组,其中删除了所有结尾的.pdf You can, if you wish put this in another array as so: 如果愿意,可以将其放在另一个数组中,如下所示:

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

All this is 100% safe regarding funny symbols in filenames (spaces, newlines, etc.), except for the echo part for files named -n.pdf , -e.pdf and -E.pdf ... but the echo was just here for demonstration purposes. 对于文件名中的有趣符号(空格,换行符等),所有这一切都是100%安全的,除了名为-n.pdf-e.pdf-E.pdf文件的echo部分...但echo只是在这里用于演示目的。 Your files=( $(ls *.pdf) ) is really really bad! 您的files=( $(ls *.pdf) )真的很糟糕! Do never parse the output of ls . 永远不要解析ls的输出


To answer your comment: substring expansions don't work on each field of the array. 回答您的评论:子字符串扩展不适用于数组的每个字段。 Taken from the reference manual linked above: 摘自上面链接的参考手册:

${parameter:offset}

${parameter:offset:length}

If offset evaluates to a number less than zero, the value is used as an offset from the end of the value of parameter . 如果offset的数值小于零,则将该值用作从parameter的值的末尾开始的偏移量。 If length evaluates to a number less than zero, and parameter is not @ and not an indexed or associative array, it is interpreted as an offset from the end of the value of parameter rather than a number of characters, and the expansion is the characters between the two offsets. 如果length计算得出的数字小于零,并且parameter不是@并且不是索引数组或关联数组,则将其解释为距parameter值末尾的偏移量,而不是字符数,并且扩展名是字符在两个偏移量之间。 If parameter is @ , the result is length positional parameters beginning at offset. 如果parameter@ ,则结果是从偏移量开始的length位置参数。 If parameter is an indexed array name subscripted by @ or * , the result is the length members of the array beginning with ${parameter[offset]} . 如果parameter是一个用@*下标的索引数组名,则结果是数组的length成员,其length${parameter[offset]} A negative offset is taken relative to one greater than the maximum index of the specified array. 相对于大于指定数组的最大索引的偏移量,取一个负偏移量。 Substring expansion applied to an associative array produces undefined results. 子字符串扩展应用于关联数组会产生不确定的结果。

So, eg, 因此,例如

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM