【问题标题】:Writing a shell conditional for extensions为扩展编写一个 shell 条件
【发布时间】:2012-01-29 21:38:46
【问题描述】:

我正在编写一个快速的 shell 脚本来一举构建和执行我的程序。

我已经把那部分记下来了,但我想包含一些 if/else 来捕捉不好的扩展 - 如果它不是 .adb(它是一个 Ada 脚本),它不会让其余的程序执行。

我的问题分为两部分:

  • 如何只获取扩展名?还是说*.adb 更容易?
  • if/else 语句是什么样的?我在 Bash 方面的经验有限,所以我知道这是一个非常糟糕的问题。

谢谢!

【问题讨论】:

    标签: bash shell


    【解决方案1】:

    有一些方法可以提取扩展名,但您实际上并不需要:

    if [[ $filename == *.adb ]] ; then
        . . . # this code is run if $filename ends in .adb
    else
        . . . # this code is run otherwise
    fi
    

    (提取扩展名的麻烦在于你必须定义你所说的“扩展名”。一个名为foo的文件的扩展名是什么?一个名为report.2012.01.29的文件怎么样?所以一般-目的扩展提取代码很棘手,如果您的目标只是确认该文件具有特定扩展名,则不值得。)

    【讨论】:

      【解决方案2】:

      有多种方法可以做到这一点。哪个最好部分取决于后续操作。

      给定一个变量$file,您可能想要测试扩展名是什么。在这种情况下,您可能会做得最好:

      extn=${file##*.}
      

      这将删除名称中最后一个点之前的所有内容、斜线和所有内容,如果文件名是 adafile.adb,则留下 adb

      另一方面,如果你想根据扩展做不同的事情,你可以使用:

      case "$file" in
      (*.adb)  ...do things with .adb files;;
      (*.pqr)  ...do things with .pqr files;;
      (*)      ...cover the rest - maybe an error;;
      esac
      

      如果您想要不带扩展名的名称,您可以使用更传统的方式:

      base=$(basename $file .adb)
      path=$(dirname $file)
      

      basename 命令为您提供文件名的最后一个组成部分,去掉了扩展名 .adbdirname 命令为您提供指向文件名最后一个组成部分的路径,如果没有指定路径,则默认为 .(当前目录)。

      最近执行这两个操作的方法是:

      base=${file##/}
      path=${file%/*}
      

      这些的优点是它们是内置操作,不会调用单独的可执行文件,因此它们更快。内置函数的缺点是,如果您的名称以斜杠结尾,则内置函数会将其视为重要,但命令不会(并且该命令可能会为您提供更理想的行为,除非您想要争论 GIGO)。

      还有其他可用的技术。 expr 命令是一种旧的、相当重量级的机制,通常不会使用(但它非常标准)。可能还有其他技术使用(( ... ))$(( ... ))[[ ... ]] 运算符来评估各种表达式。

      【讨论】:

      • 小心${file##*.},因为如果文件名没有句点,它会表现得很糟糕。更糟糕的是,如果它的父目录带有句点,而文件名没有(例如 file="/parentdir/dir.d/subdir/filename" -> extn="d/subdir/filename")。
      • @Gordon:谢谢你的警告——我仍然更喜欢老式的做事方式,主要是。不过,我永远不太确定,我是否只是懒于学习新技术,还是旧的、真实的、久经考验的技术是否真的更好。我经常认为,旧的至少有足够的优势还没有被淘汰。
      【解决方案3】:

      要仅从文件路径和名称中获取扩展名,请使用参数扩展:

      ${filename##*.} # deletes everything to the last dot
      

      要将它与字符串 adb 进行比较,只需这样做

      if [[ ${filename##*.} != adb ]] ; then
          echo Invalid extension at "$filename".
          exit 1
      fi
      

      或者,使用“else”:

      if [[ ${filename##*.} != adb ]] ; then
          echo Invalid extension at "$filename".
      else
          # Run the script...
      fi
      

      【讨论】:

        【解决方案4】:

        扩展名:

        fileext=`echo $filename | sed 's_.*\.__'`
        

        测试

        if [[ x"${fileext}" = "xadb" ]] ; then
          #do something
        fi
        

        【讨论】:

        • @ruakh:你是对的,谢谢你的指出!我已经更新了我的答案。
        猜你喜欢
        • 2011-06-12
        • 1970-01-01
        • 2014-08-18
        • 2012-02-07
        • 2012-01-08
        • 2020-11-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多