在 Bash 中获取文件的扩展名

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/44217138/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 16:11:35  来源:igfitidea点击:

Get extension of files in Bash

stringbashfilenames

提问by SigGP

I am writing a script which will sort files by extensions. I know a method to do this by file's names. The problem is, that same files haven't got extension in their names. For example if I have file: file.txtthere is no problem to get an extension by simple extension="${filename##*.}". But if file name is just filenamethis method doesn't work. Is there any other option to get extension of file and put it to variable in Bash script?

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

采纳答案by FedericoCapaldo

It seems that you are only asking how to put the file extension of a filename into a variable in bash, and you are not asking about the sorting part. To do so, the following brief script can print the extension of each file from a file list.

看来你只是问如何将文件名的文件扩展名放入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

the variable that contains the extention of the current file analysed is called extention. The command sed 's/^\w\+.//matched any length of characters until the first dot found in the filename and then removes it. Therefore if there are multiple file extentions these would be all listed (e.g. file.txt-> get extention txtbut file.odt.pdf-> get extention odt.pdf).

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

EXAMPLE

例子

Current Folder content (this can be any space-separated list of files that you feed to the loop)

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

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

Result of script above:

上面脚本的结果:

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

In this way, files with no extension will result in the extension variable being empty.

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

回答by Jens

Without bashisms like [[:

没有像这样的bashisms [[

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

Works in any Bourne-heritage shell.

适用于任何 Bourne-heritage shell。

回答by Cyrus

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

Output:

输出:

txt


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

Output:

输出:

no extension

回答by chepner

You can get the base name of the file by removingthe extension, the removing thatfrom the original.

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

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

I like the casestatement more, though; the intent is clearer.

不过,我case更喜欢这句话;意图更加明确。

回答by George Vasiliou

For a situation like:

对于这样的情况:

$ ls file*
file1  file1.txt  file2  

You can do something like:

您可以执行以下操作:

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