获取 Bash 中的文件扩展名

Get extension of files in Bash

我正在编写一个脚本,它将按扩展名对文件进行排序。我知道一种通过文件名执行此操作的方法。问题是,相同的文件在名称中没有扩展名。例如,如果我有文件:file.txt,通过简单的 extension="${filename##*.}" 获得扩展名是没有问题的。但是如果文件名只是 filename 这个方法就不行了。是否有任何其他选项来获取文件扩展名并将其放入 Bash 脚本中的变量?

filename="file.txt"
ext="${filename##*.}"
if [[ "$ext" != "$filename" ]]; then echo "$ext"; else echo "no extension"; fi

输出:

txt

filename="file"
ext="${filename##*.}"
if [[ "$ext" != "$filename" ]]; then echo "$ext"; else echo "no extension"; fi

输出:

no extension

没有像 [[ 这样的 bashism:

case $filename in
  (.*.*) extension=${filename##*.};;
  (.*)   extension="";;
  (*.*)  extension=${filename##*.};;
  (*)    extension="";;
esac

适用于任何 Bourne-heritage shell。

您可以通过删除 扩展名,从原始文件中删除that 来获取文件的基本名称。

base=${filename%.*}
ext=${filename#$base.}

不过我更喜欢case的说法;意图更明确。

对于这样的情况:

$ ls file*
file1  file1.txt  file2  

您可以这样做:

$ ls file* |awk -F. '{print (NF>1?$NF:"no extension")}'
no extension
txt
no extension

看来你只是问bash中如何将文件名的文件扩展名放入变量中,而没有问排序部分。 为此,以下简短脚本可以打印文件列表中每个文件的扩展名。

#!/bin/sh
filesInCurrentDir=`ls`
for file in $filesInCurrentDir; do
    extention=`sed 's/^\w\+.//' <<< "$file"`
    echo "the extention for $file is: "$extention #for debugging
done

包含当前分析文件扩展名的变量称为extention。命令 sed 's/^\w\+.// 匹配任意长度的字符,直到在文件名中找到第一个点,然后将其删除。因此,如果有多个文件扩展名,这些将全部列出(例如 file.txt -> 获取扩展名 txtfile.odt.pdf -> 获取扩展名 odt.pdf)。

例子

当前文件夹内容(这可以是您提供给循环的任何 space 分隔的文件列表)

aaab.png
abra
anme2.jpg
cadabra
file
file.png
file.txt
loacker.png
myText
name.pdf
rusty.jgp

上面脚本的结果:

the extention of aaab.png is: png
the extention of abra is: 
the extention of anme2.jpg is: jpg
the extention of cadabra is: 
the extention of file is: 
the extention of file.png is: png
the extention of file.txt is: txt
the extention of loacker.png is: png
the extention of myText is: 
the extention of name.pdf is: pdf
the extention of rusty.jgp is: jgp

这样,没有扩展名的文件会导致扩展名变量为空。