我试图编写一个函数来改变当前目录中所有匹配文件的扩展名:
function chext
if count $args -eq 2 > /dev/null
for f in (ls *$argv[1])
mv (basename $f $argv[2]) (basename $f $argv[1])
end
else
echo "Error: use the following syntax"
echo "chext oldext newext"
end
end
我不断得到这个输出:
(*master) λ chext markdown txt
No matches for wildcard '*$argv[1]'. (Tip: empty matches are allowed in 'set', 'count', 'for'.)
~/.config/fish/config.fish (line 1): ls *$argv[1]
^
in command substitution
called on line 60 of file ~/.config/fish/config.fish
in function 'chext'
called on standard input
with parameter list 'markdown txt'
我知道必须有一种方法来插入变量并将*
保留为通配符,但我无法弄明白。我尝试使用(string join '*' $argv[1])
,但它将通配符转换为字符串。
我确实得到了几乎的工作:
function chext
if count $args -eq 2 > /dev/null
for f in (ls (string join * $argv[1]))
mv (basename $f $argv[2]) (basename $f $argv[1])
end
else
echo "Error: use the following syntax"
echo "chext oldext newext"
end
end
它从我的所有文件中删除了扩展,但没有添加新文件,然后给了我一个错误,即所有文件名合并,文件名太长了。
更新:
我确定有办法让正确ls
正常工作,但我确实成功了:
if count $args -eq 2 > /dev/null
for f in (ls)
mv $f (string replace -r \.$argv[1]\$ .$argv[2] (basename $f))
end
else
echo "Error: use the following syntax"
echo "chext oldext newext"
end
end
答案 0 :(得分:3)
答案在信息中:
没有匹配的通配符'* $ argv [1]'。 (提示:'strong','count','for'允许空匹配。)
这意味着
for i in *argv[1]
和
一样有用set -l expanded *argv[1]
如果您尝试使用与任何内容都不匹配的glob启动任何其他命令,fish将跳过执行并打印错误。
您的功能还有许多其他问题,请允许我逐一浏览。
如果计数$ args -eq 2>的/ dev / null的
count
不接受“-eq 2”参数。
您尝试做的是if test (count $args) -eq 2
。
什么也有效(以及我喜欢的更多)是if set -q argv[2]
(另外,它是“arg v ”,而不是“args”)。
表示f in(ls * $ argv [1])
请不要使用ls
的输出。它在鱼类中没有像在bash中那样多的问题(一旦文件在名称中有空格,制表符或换行符就会中断),但这是不必要的(它启动了一个额外的过程)并且仍然有问题 - 当文件名称中有换行符时它会中断。
只需for f in *$argv[1]
,这也很好地解决了你的问题。
mv (basename $f $argv[2]) (basename $f $argv[1])
我不确定你在这里使用的basename
是什么,但我只是删除了后缀。因此,如果您执行chext .opus .ogg
,则会执行
mv (basename song.opus .ogg) (basename song.opus .opus)
将解析为
mv song.opus song
就个人而言,我会使用string replace
。像
mv $f (string replace -- $argv[1] $argv[2] $f)
(注意:如果之前出现扩展字符串,这会出错,例如,如果您有一个名为“f.ogg-banana.ogg”的文件,则只会更改第一个“.ogg”。您可能希望使用正则表达式:string replace -r -- "$argv[1]\$" $argv[2] $f
)