匹配文件名的前几个字母:Shell script



我正在尝试匹配文件的前几个字母。

for entry in `ls`; do
    echo $entry
done
使用上面的代码,我得到了所有文件的名称。

开头有几个文件名相似的文件:

Beaglebone-v1
Beaglebone-v3
Beaglebone-v2

我如何比较$entry与Beaglebone*,然后提取最新版本文件名?

如果要遍历所有Beaglebone-*文件:

for entry in Beaglebone-* ; do
    echo $entry
done

如果您只需要最新版本的文件,您可以依赖ls按字母顺序对您的名称进行排序的事实,因此您可以这样做:

LATEST_FILE_NAME=$(ls Beaglebone-* | tail -n 1)

将按字母顺序取最后一个

要处理较大的数字,可以使用如下的数值比较:

stem="Beaglebone-v"
for file in $stem*; do 
    ver=${file#"$stem"}          # cut away stem to get version number        
    (( ver > max )) && max=$ver  # conditionally assign `ver` to `max` 
done
echo "$stem$max"

测试:

bash-4.3$ ls Beaglebone-v*
Beaglebone-v1  Beaglebone-v10  Beaglebone-v2  Beaglebone-v3
bash-4.3$ stem="Beaglebone-v" &&
for file in $stem*
  do
    ver=${file#"$stem"}
    (( ver > max )) && max=$ver
  done; echo "$stem$max"
Beaglebone-v10

您可以将匹配模式的文件名存储在数组中,然后选择数组的最后一个元素。

shopt -s nullglob
arr=( Beaglebone-* )
if (( ${#arr[@]} > 0 ))
then
    latest="${arr[ (( ${#arr[@]} - 1 )) ]}"
    echo "$latest"
fi

您需要启用nullglob,以便如果没有匹配模式的文件,您将得到一个空数组,而不是模式本身。

如果版本号可以超过个位数,

function version_numbers {
    typeset w; for w in $1-v*; do echo ${w#$1-v}; done
}
version_numbers "Beaglebone" | sort -n | tail -1

或,增加函数max:

# read a stream of numbers, from stdin (one per line)
# and return the largest value
function max
{
  typeset _max n
  read _max || return
  while read n; do
    ((_max < n)) && _max=$n
  done
  echo $_max
}

我们现在不需要外部命令就可以完成整个操作:

version_numbers Beaglebone | max

注意,如果任何一行没有完成数值比较,max将会失败。

最新更新