在 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
Get extension of files in Bash
提问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.txt
there is no problem to get an extension by simple extension="${filename##*.}"
. But if file name is just filename
this 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 txt
but file.odt.pdf
-> get extention odt.pdf
).
包含当前分析文件扩展名的变量称为extention
。该命令sed 's/^\w\+.//
匹配任何长度的字符,直到在文件名中找到第一个点,然后将其删除。因此,如果有多个文件扩展名,这些将全部列出(例如file.txt
-> 获取扩展名txt
但file.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 case
statement 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