Bash - 用函数缩短脚本

时间:2018-02-05 11:53:48

标签: bash

在我的脚本中,我需要两次获得最大数量的文件,所以我想创建一个函数。这是脚本中的命令:

第一次:

highest=$( ls $path.bak.* | sort -t"." -k2 -n | tail -n1 | sed -r 's/.*\.(.*)/\1/')

第二次:

newhighest=$(ls $path.bak.* | sort -t"." -k2 -n | tail -n1 | sed -r 's/.*\.(.*)/\1/')

现在我的问题: 如何用函数缩短这个?

这是我的输入文件:

  • test.bak.1
  • test.bak.2
  • test.bak.3
  • test.bak.4
  • test.bak.5
  • test.bak.6
  • test.bak.7
  • test.bak.8
  • test.bak.9
  • test.bak.10
  • test.bak.11

预期回报:11

1 个答案:

答案 0 :(得分:3)

为便于阅读而写出:

#!/usr/bin/env bash
#              ^^^^ - Ensure that this script is run with bash, not /bin/sh

# Enable "extended globs", so we can exclude names that don't end with digits
shopt -s extglob

# since your files are test.bak.*
path=test

get_highest() {
  # set the function's argument list
  set -- "$path".bak.+([[:digit:]])

  # if we have just one valid filename, we know the glob expanded successfully.
  # otherwise, no such files exist, so exit the function immediately
  [[ -e $1 || -L $1 ]] || return 1

  # stream our list of extensions into sort, and let awk find the highest number
  printf '%s\n' "${@##*.}" | awk '$0>last{last=$0}END{print last}'
}

highest=$(get_highest) || { echo "No backup files found" >&2; exit 1; }
new_highest=$(get_highest) || { echo "No backup files on 2nd pass" >&2; exit 1; }

注意:

  • 需要引用扩展;在"$path"/*$path/*作为结果发布后,path="Directory With Spaces/test",而非Spaces/testDirectory会在With中查找文件。
  • ls should never be used programatically.
  • extglob syntax允许使用类似正则表达式的功能来匹配文件组,让我们在此声明我们只考虑以.bak.后跟数字的文件名。
  • 一般情况下,您应该将脚本编写为易于阅读和理解,而不是将其编写为简短。你未来的自我(以及其他需要在将来维护代码的人)会感谢你。
  • 由于换行符可以包含在文件名中,因此使用分隔流中的文件名是不安全的。当名称没有被引用或转义时,只有NUL字符对于此用途是安全的。因此,在发出任意名称的流时,应使用字符串%s\0对其进行格式化,并使用-z参数进行排序。 但是,我们只在这里打印数字扩展,使换行安全。