在Bash中获取文件扩展名

9

我正在编写一个脚本,用于按扩展名对文件进行排序。我知道一种方法可以通过文件名来实现此目的。问题是,有些文件名中没有扩展名。例如,如果我有一个文件: file.txt,通过简单的extension="${filename##*.}"就可以轻松获取扩展名。但如果文件名只是filename,这种方法就不起作用了。在Bash脚本中有没有其他选项可以获取文件的扩展名并将其放入变量中?


5个回答

11
你可以通过删除文件扩展名,然后从原始文件名中移除它来获得文件的基本名称。
base=${filename%.*}
ext=${filename#$base.}

我更喜欢case语句,因为它的意图更清晰。


这段代码实际上会在没有扩展名的情况下返回 $filename。通过添加另一个步骤,您可以使其在没有扩展名的情况下返回 ""。 extension_echo () { file=$1; base=${file%.*}; ext=${file#$base}; ext=${ext#.}; echo "$ext";} - marinara

10
没有使用bashism的话,如[[
case $filename in
  (.*.*) extension=${filename##*.};;
  (.*)   extension="";;
  (*.*)  extension=${filename##*.};;
  (*)    extension="";;
esac

可以在任何Bourne风格的shell中使用。


6
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

输出:

没有文件扩展名

但问题是,这些没有扩展名的文件实际上可能是txt或jpg文件,而我需要将它们放到正确的文件夹中。 - SigGP

2

对于这样的情况:

$ ls file*
file1  file1.txt  file2  

您可以这样做:

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

0

看起来你只是在询问如何将文件名的文件扩展名放入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 -> 获取扩展名txt,但file.odt.pdf -> 获取扩展名odt.pdf)。

示例

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

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

以这种方式,没有扩展名的文件将导致扩展变量为空。

对于那些给我点“踩”(downvote)的人:如果你能告诉我哪里错了,我可以重新审视我的回答。 - Fed
3
虽然我没有给你点踩,但我需要告诉你,你的解决方案很容易出问题。只需运行 touch "file spaced.txt" 并测试你的代码即可。此外,搜索一下为什么不应该解析 ls 的输出以及如何使用 for 和 globing(即 for file in *)循环文件 - 另一个灰色区域是在 bash 已经配备了可以带来所需结果的参数扩展的情况下使用 sed。这就像在露天游乐场使用机关枪赢得泰迪熊一样。此外,并非所有的 sed 版本都能够正常工作。 - George Vasiliou

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接