【发布时间】:2015-06-03 09:17:27
【问题描述】:
有什么方便的方法可以从文件名中去除任意扩展名,比如 bash ${i%%.*}?我会坚持我的朋友sed吗?
【问题讨论】:
标签: fish
有什么方便的方法可以从文件名中去除任意扩展名,比如 bash ${i%%.*}?我会坚持我的朋友sed吗?
【问题讨论】:
标签: fish
如果您知道扩展名(例如 _bak,一个常见的用例),这可能更方便:
for f in (ls *_bak)
mv $f (basename $f _bak)
end
【讨论】:
不。 fish 的功能集比 bash 小得多,依赖于外部命令:
$ set filename foo.bar.baz
$ set rootname (echo $filename | sed 's/\.[^.]*$//')
$ echo $rootname
foo.bar
【讨论】:
string命令可以在不使用外部命令的情况下达到相同的效果。
/this/is.another/test 给出 /this/is
您可以使用string 命令从文件名中去除扩展名:
echo (string split -r -m1 . $filename)[1]
这将在最右边的点处拆分filename 并打印结果列表的第一个元素。如果没有点,则该列表将包含一个带有 filename 的元素。
如果您还需要剥离前导目录,请将其与 basename 结合起来:
echo (basename $filename | string split -r -m1 .)[1]
在本例中,string 从标准输入读取其输入,而不是将文件名作为命令行参数传递。
【讨论】:
--field (-f) 来选择第一个字段,而不是使用[1]。示例:string split --right --max 1 --field 1 . $filename;另外我认为你不需要echo,因为string split 已经打印输出了。
/this/is.another/test 给出/this/is
使用鱼内置的string match 函数,您可以做到
set rootname (string match -r "(.*)\.[^\.]*\$" $filename)[2]
字符串匹配返回一个包含 2 个项目的列表。第一个是整个字符串,第二个是第一个正则表达式匹配(正则表达式括号内的东西)。所以,我们用 [2] 抓取第二个。
【讨论】:
/this/is.another/test 给出/this/is
fishstring 命令仍然是处理此问题的规范方法。它有一些非常好的子命令,尚未在其他答案中显示。
split 允许您从右侧拆分,最大值为 1,这样您就可以得到最后一个扩展名。
for f in *
echo (string split -m1 -r '.' "$f")[1]
end
replace 允许您使用正则表达式来删除扩展名,定义为字符串末尾的最后一个点
for f in *
string replace -r '\.[^\.]*$' '' "$f"
end
man string 了解更多信息和一些很好的例子。
-- 更新--
如果您的系统有正确的basename 和dirname 实用程序,您可以使用这样的工具:
function stripext \
--description "strip file extension"
for arg in $argv
echo (dirname $arg)/(string replace -r '\.[^\.]+$' '' (basename $arg))
end
end
【讨论】:
/this/is.another/test 给出/this/is
path 实用程序进入 Fish:github.com/fish-shell/fish-shell/pull/8265
我也需要一个函数来拆分随机文件的根目录和扩展名。与其冒着遇到警告的风险(例如:分隔符前的点)天真地重新实现该功能,我将任务转发给 Python 的内置 POSIX path 库并继承他们的专业知识。
下面是一个简单的例子,说明人们可能更喜欢什么:
function splitext --description "Print filepath(s) root, stem or extension"
argparse 'e/ext' 's/stem' -- $argv
for arg in $argv
if set -q _flag_ext
set cmd 'import os' \
"_, ext = os.path.splitext('$arg')" \
'print(ext)'
else if set -q _flag_stem
set cmd 'from pathlib import Path' \
"p = Path('$arg')" \
'print(p.stem)'
else
set cmd 'import os' \
"root, _ = os.path.splitext('$arg')" \
'print(root)'
end
python3 -c (string join ';' $cmd)
end
end
例子:
$ splitext /this/is.a/test.path
/this/is.a/test
$ splitext --ext /this/is.a/test.path
.path
$ splitext --stem /this/is.a/test.path
test
$ splitext /this/is.another/test
/this/is.another/test
【讨论】: