bash 在不知情的情况下从文件中删除扩展名

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5365090/
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-17 23:38:25  来源:igfitidea点击:

removing extension from file without knowing it

bash

提问by Flethuseo

I know how to remove the extension of a file, when I know it as:

我知道如何删除文件的扩展名,当我知道它时:

nameis=$(basename $dataset .csv)

but I want to remove any extension without knowing it beforehand, anyone know how to do this?

但我想在事先不知情的情况下删除任何扩展名,有人知道该怎么做吗?

Any help appreciated, Ted

任何帮助表示赞赏,泰德

回答by Mark Longair

In bash you can do the following:

在 bash 中,您可以执行以下操作:

nameis=${dataset%.*}

... e.g.:

...例如:

$ dataset=foo.txt
$ nameis=${dataset%.*}
$ echo $nameis
foo

This syntax is described in the bash man page as:

此语法在 bash 手册页中描述为:

${parameter%word}

${parameter%%word}

Remove matching suffix pattern. The word is expanded to produce a pattern just as in pathname expansion. If the pattern matches a trailing portion of the expanded value of parameter, then the result of the expansion is the expanded value of parameter with the shortest matching pattern (the "%" case) or the longest matching pattern (the "%%" case) deleted. If parameter is @ or *, the pattern removal operation is applied to each positional parameter in turn, and the expansion is the resultant list. If parameter is an array variable subscripted with @ or *, the pattern removal operation is applied to each member of the array in turn, and the expansion is the resultant list.

${参数%word}

${参数%%word}

删除匹配的后缀模式。这个词被扩展以产生一个模式,就像在路径名扩展中一样。如果模式匹配参数扩展值的尾随部分,则扩展的结果是具有最短匹配模式(“%”情况)或最长匹配模式(“%%”情况)的参数的扩展值) 删除。如果参数为@或*,则依次对每个位置参数应用模式移除操作,扩展为结果列表。如果参数是一个带有@或*下标的数组变量,模式移除操作依次应用于数组的每个成员,扩展为结果列表。

回答by user4853039

Now, if you want some stylish old-school regexp:

现在,如果你想要一些时尚的老式正则表达式:

echo "foo.bar.tar.gz" | sed "s/^\(.*\)\..*$//"

-> Shall return: foo.bar.tar

-> 应返回:foo.bar.tar

I will break it down: 
s/   Substitute
^      From the beginning
\(     Mark
.*     Everything (greedy way)
\)     Stop Marking (the string marked goes to buffer 1)
\.     until a "." (which will be the last dot, because of the greedy selection)
.*     select everything (this is the extension that will be discarded)
$      until the end
/    With (substitute)
      The buffer 1 marked above (which is the filename before the last dot(.)
/    End

Cristiano Savino

克里斯蒂亚诺·萨维诺

回答by PCat

nameis=${dataset%%.*} Assumes none of your basenames have a dot in it. This returns the longest possible dotless string from the left.

nameis=${dataset%%.*} 假设您的基本名称中都没有点。这将从左侧返回最长的无点字符串。

回答by geekosaur

Something like ${dataset%.*}might work; beware of files withoutextensions, though, as it will look for a dot that's not part of an extension to chop off.

类似的东西${dataset%.*}可能会起作用;但是,请注意没有扩展名的文件,因为它会寻找一个不属于扩展名的点来砍掉。

回答by Fred Foo

You could remove everything following the last dot, if any, with sed:

您可以使用以下命令删除最后一个点之后的所有内容(如果有)sed

nameis=$(echo $filename | sed 's/\.[^.]*$//')

But that would not work on files with double extensions such as .tar.gz.

但这不适用于具有双扩展名的文件,例如.tar.gz.

回答by anubhava

I would suggest instead of basenameuse sedcommand for that, like this:

我建议不要为此basename使用sed命令,如下所示:

echo "$fileName" | sed 's/\..*$//g'

echo "$fileName" | sed 's/\..*$//g'