如何在bash脚本中检查文件名的扩展名?

153 bash scripting file

我正在用bash编写一个每晚构建脚本.
一切都很好,花花公子除了一个小小的障碍:


#!/bin/bash

for file in "$PATH_TO_SOMEWHERE"; do
      if [ -d $file ]
      then
              # do something directory-ish
      else
              if [ "$file" == "*.txt" ]       #  this is the snag
              then
                     # do something txt-ish
              fi
      fi
done;
Run Code Online (Sandbox Code Playgroud)

我的问题是确定文件扩展名,然后相应地采取行动.我知道问题出在if语句中,测试txt文件.

如何确定文件后缀是否为.txt?

小智 243

使

if [ "$file" == "*.txt" ]
Run Code Online (Sandbox Code Playgroud)

像这样:

if [[ $file == *.txt ]]
Run Code Online (Sandbox Code Playgroud)

也就是说,双括号,没有引号.

右侧==是贝壳图案.如果需要正则表达式,请使用=~.

  • 我是bash的新手,我花了一些时间来弄清楚如何在多条件`if`语句中使用它.我在这里分享它,以防它帮助某人.`if [[($ file ==*.csv)|| ($ file ==*.png)]]` (18认同)
  • 我不知道这件事.似乎是一种特殊情况,==或!=的右侧扩展为shell模式.我个人认为这比我的答案更清楚. (15认同)
  • @cheflo对一般的多种情况都有好处.在这种特殊情况下,你也可以使用`if [[$ file =〜.*\.(csv | png)]]`.它更短,更清晰,更容易添加额外的扩展,并且可以轻松地进行配置(通过将"csv | png"放在变量中). (4认同)
  • 您可以在文件周围加上双引号.`if [["$ file"==*.txt]]`如果文件名中有空格,则需要双引号. (3认同)
  • @shawnhcorey 不需要引用 $file,即使它包含空格。[[ 命令不进行分词(也不进行路径名扩展)。这是 [[ 和 [ 之间的主要区别之一,也是使用 [[ 的主要原因之一。 (3认同)
  • @shawnhcorey,它也没有引号. (2认同)
  • 我应该使用这个答案而不是接受的答案吗? (2认同)

Pau*_*son 224

我想你想说"$ file的最后四个字符是否等于.txt?" 如果是这样,您可以使用以下内容:

if [ ${file: -4} == ".txt" ]
Run Code Online (Sandbox Code Playgroud)

需要注意的是之间的空间file:-4需要,为" - "修饰符意味着不同的东西.

  • 如果要指定不等式,请记住包括额外的括号:if [[$ {file:-4}!=".txt"]] (9认同)
  • @RamRajamony为什么有必要使用[[测试不平等时? (4认同)
  • 在 bash 中,除非您在第一个变量周围加上引号,否则这将产生“[:==:预期一元运算符”错误。所以改为 `if [ "${file: -4}" == ".txt" ]` 。 (3认同)

Eld*_*ell 26

你不能确定在Unix系统上,.txt文件确实是一个文本文件.你最好的选择是使用"文件".也许尝试使用:

file -ib "$file"
Run Code Online (Sandbox Code Playgroud)

然后,您可以使用MIME类型列表来匹配或解析MIME的第一部分,您可以在其中获取"text","application"等内容.

  • 由于`file -i ...`包含mime编码,你可以使用`file --mime-type -b ...` (2认同)

Ada*_*eck 24

如果您确实想要查找有关该文件的信息而不是依赖于扩展,则可以使用"file"命令.

如果您对使用扩展程序感到满意,可以使用grep查看它是否匹配.


kvz*_*kvz 15

你也可以这样做:

   if [ "${FILE##*.}" = "txt" ]; then
       # operation for txt files here
   fi
Run Code Online (Sandbox Code Playgroud)

  • `case $ FILE in*.txt)... ;; esac`看起来更加健壮和惯用. (9认同)
  • 这将与最基本的 shell 配合使用,更加通用。 (3认同)

小智 11

关于如何在 linux 中获取文件名中可用扩展名的正确答案是:

${filename##*\.} 
Run Code Online (Sandbox Code Playgroud)

打印目录中所有文件扩展名的示例

for fname in $(find . -maxdepth 1 -type f) # only regular file in the current dir
    do  echo ${fname##*\.} #print extensions 
done
Run Code Online (Sandbox Code Playgroud)


dar*_*aud 8

与'file'类似,使用稍微简单的'mimetype -b',无论文件扩展名如何,都可以使用.

if [ $(mimetype -b "$MyFile") == "text/plain" ]
then
  echo "this is a text file"
fi
Run Code Online (Sandbox Code Playgroud)

编辑:如果mimetype不可用,您可能需要在系统上安装libfile-mimeinfo-perl