Bash substring expansion on array

不打扰是莪最后的温柔 提交于 2019-12-08 02:04:28

问题


I have a set of files with a given suffix. For instance, I have a set of pdf files with suffix .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..

( I would like to avoid using a for loop )


回答1:


Use parameter expansions to remove the .pdf part like so:

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.

"${files[@]%.pdf}" will expand to an array with all the trailing .pdf removed. 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. Your files=( $(ls *.pdf) ) is really really bad! Do never parse the output of 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. 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. If parameter is @, the result is length positional parameters beginning at offset. If parameter is an indexed array name subscripted by @ or *, the result is the length members of the array beginning with ${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, e.g.,

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


来源:https://stackoverflow.com/questions/20160838/bash-substring-expansion-on-array

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!